Merge branch 'master' into sysmgrtooltip_syschaninfo
This commit is contained in:
commit
e50b3438f2
834 changed files with 780920 additions and 160607 deletions
|
|
@ -23,39 +23,40 @@
|
|||
|
||||
const char* aboutLine[]={
|
||||
"tildearrow",
|
||||
"is proud to present",
|
||||
_N("is proud to present"),
|
||||
"",
|
||||
("Furnace " DIV_VERSION),
|
||||
"",
|
||||
"the biggest multi-system chiptune tracker!",
|
||||
"featuring DefleMask song compatibility.",
|
||||
_N("the biggest multi-system chiptune tracker!"),
|
||||
_N("featuring DefleMask song compatibility."),
|
||||
"",
|
||||
"> CREDITS <",
|
||||
_N("> CREDITS <"),
|
||||
"",
|
||||
"-- program --",
|
||||
_N("-- program --"),
|
||||
"tildearrow",
|
||||
"A M 4 N (intro tune)",
|
||||
_N("A M 4 N (intro tune)"),
|
||||
"akumanatt",
|
||||
"cam900",
|
||||
"djtuBIG-MaliceX",
|
||||
"Eknous",
|
||||
"Kagamiin~",
|
||||
"laoo",
|
||||
"LTVA1",
|
||||
"LTVA",
|
||||
"MooingLemur",
|
||||
"OPNA2608",
|
||||
"scratchminer",
|
||||
"superctr",
|
||||
"System64",
|
||||
"techmetx11",
|
||||
"",
|
||||
"-- graphics/UI design --",
|
||||
_N("-- graphics/UI design --"),
|
||||
"tildearrow",
|
||||
"BlastBrothers",
|
||||
"Electric Keet",
|
||||
"Mahbod Karamoozian",
|
||||
"Raijin",
|
||||
"",
|
||||
"-- documentation --",
|
||||
_N("-- documentation --"),
|
||||
"brickblock369",
|
||||
"cam900",
|
||||
"DeMOSic",
|
||||
|
|
@ -65,12 +66,27 @@ const char* aboutLine[]={
|
|||
"Lunathir",
|
||||
"tildearrow",
|
||||
"",
|
||||
"-- demo songs --",
|
||||
_N("-- localization/translation team --"),
|
||||
"Bahasa Indonesia: ZoomTen (Zumi)",
|
||||
"Español: CrimsonZN, ThaCuber, tildearrow",
|
||||
"Հայերեն: Eknous",
|
||||
"한국어: Heemin, leejh20",
|
||||
"Nederlands: Lunathir",
|
||||
"Polski: freq-mod, PoznańskiSzybkowiec",
|
||||
"Português (Brasil): Kagamiin~",
|
||||
"Русский: Background2982, LTVA",
|
||||
"Slovenčina: Wegfrei",
|
||||
"Svenska: RevvoBolt",
|
||||
"ไทย: akumanatt",
|
||||
"",
|
||||
_N("-- demo songs --"),
|
||||
"0x5066",
|
||||
"Abstract 64",
|
||||
"Aburtos",
|
||||
"ActualNK358",
|
||||
"Aishi Tsukumo",
|
||||
"akumanatt",
|
||||
"aloelucidity",
|
||||
"AmigaX",
|
||||
"AquaDoesStuff",
|
||||
"AURORA*FIELDS",
|
||||
|
|
@ -78,6 +94,7 @@ const char* aboutLine[]={
|
|||
"battybeats",
|
||||
"bbqzzd",
|
||||
"Bernie",
|
||||
"billimanmcjonnson",
|
||||
"BlastBrothers",
|
||||
"Blaze Weednix",
|
||||
"BlueElectric05",
|
||||
|
|
@ -96,10 +113,12 @@ const char* aboutLine[]={
|
|||
"dmKaltsit",
|
||||
"Dolce",
|
||||
"dumbut",
|
||||
"Eggo1423",
|
||||
"Eknous",
|
||||
"Electric Keet",
|
||||
"EntropyAuthor",
|
||||
"EpicTyphlosion",
|
||||
"Ether Egg",
|
||||
"FΛDE",
|
||||
"Forte",
|
||||
"Fragmare",
|
||||
|
|
@ -119,20 +138,21 @@ const char* aboutLine[]={
|
|||
"Laggy",
|
||||
"leejh20",
|
||||
"LovelyA72",
|
||||
"LTVA1",
|
||||
"LTVA",
|
||||
"LunaMoth",
|
||||
"Lunathir",
|
||||
"LVintageNerd",
|
||||
"Mahbod Karamoozian",
|
||||
"Marisa Kirisame [DJ MasterSpark]",
|
||||
"Martin Demsky",
|
||||
"masicbemester",
|
||||
"MelonadeM",
|
||||
"Miker",
|
||||
"Molkirill",
|
||||
"MrCoolDude",
|
||||
"NeoWar",
|
||||
"Nerreave",
|
||||
"niffuM",
|
||||
"Nikku4211",
|
||||
"<nk>",
|
||||
"Notakin",
|
||||
"nwcr",
|
||||
|
|
@ -140,27 +160,33 @@ const char* aboutLine[]={
|
|||
"Pale Moon",
|
||||
"PeyPey",
|
||||
"PichuMario",
|
||||
"pixelated",
|
||||
"Poltvick",
|
||||
"PotaJoe",
|
||||
"potatoTeto",
|
||||
"psxdominator",
|
||||
"Raijin",
|
||||
"railzen7",
|
||||
"Rancastor",
|
||||
"Rei8bit",
|
||||
"RepellantMold",
|
||||
"RetroCarrot",
|
||||
"RevvoBolt",
|
||||
"Rockyfan75000",
|
||||
"Roostersox",
|
||||
"scooblee",
|
||||
"sheffield^2",
|
||||
"sillygoose",
|
||||
"Slightly Large NC",
|
||||
"smaybius",
|
||||
"SnugglyBun",
|
||||
"Someone64",
|
||||
"Spinning Square Waves",
|
||||
"src3453",
|
||||
"SuperJet Spade",
|
||||
"Supper_E1",
|
||||
"SwapXFO",
|
||||
"Swirly",
|
||||
"System64",
|
||||
"TakuikaNinja",
|
||||
"tapekeep",
|
||||
|
|
@ -180,13 +206,14 @@ const char* aboutLine[]={
|
|||
"Ultraprogramer",
|
||||
"UserSniper",
|
||||
"Weeppiko",
|
||||
"Wegfrei",
|
||||
"Xan",
|
||||
"Yuzu4K",
|
||||
"Zabir",
|
||||
"Zaxolotl",
|
||||
"ZoomTen (Zumi)",
|
||||
"",
|
||||
"-- additional feedback/fixes --",
|
||||
_N("-- additional feedback/fixes --"),
|
||||
"Electric Keet",
|
||||
"fd",
|
||||
"GENATARi",
|
||||
|
|
@ -197,99 +224,116 @@ const char* aboutLine[]={
|
|||
"plane",
|
||||
"TheEssem",
|
||||
"",
|
||||
"powered by:",
|
||||
"Dear ImGui by Omar Cornut",
|
||||
"SDL2 by Sam Lantinga",
|
||||
_N("-- Metal backend test team --"),
|
||||
"Diggo",
|
||||
"konard",
|
||||
"NaxeCode",
|
||||
"scratchminer",
|
||||
"",
|
||||
_N("-- DirectX 9 backend test team --"),
|
||||
"EpicTyphlosion",
|
||||
"Lunathir",
|
||||
"Mr. Hassium",
|
||||
"wbcbz7",
|
||||
"Yuzu4K",
|
||||
"",
|
||||
_N("powered by:"),
|
||||
_N("Dear ImGui by Omar Cornut"),
|
||||
_N("SDL2 by Sam Lantinga"),
|
||||
#ifdef HAVE_FREETYPE
|
||||
"FreeType",
|
||||
#endif
|
||||
"zlib by Jean-loup Gailly",
|
||||
"and Mark Adler",
|
||||
"libsndfile by Erik de Castro Lopo",
|
||||
"Portable File Dialogs by Sam Hocevar",
|
||||
"Native File Dialog by Frogtoss Games",
|
||||
_N("zlib by Jean-loup Gailly"),
|
||||
_N("and Mark Adler"),
|
||||
_N("libsndfile by Erik de Castro Lopo"),
|
||||
_N("Portable File Dialogs by Sam Hocevar"),
|
||||
_N("Native File Dialog by Frogtoss Games"),
|
||||
"PortAudio",
|
||||
"Weak-JACK by x42",
|
||||
"RtMidi by Gary P. Scavone",
|
||||
"FFTW by Matteo Frigo and Steven G. Johnson",
|
||||
"backward-cpp by Google",
|
||||
"adpcm by superctr",
|
||||
"adpcm-xq by David Bryant",
|
||||
"Nuked-OPL3/OPLL/OPM/OPN2/PSG by nukeykt",
|
||||
"YM3812-LLE, YMF262-LLE and YMF276-LLE by nukeykt",
|
||||
"ESFMu (modified version) by Kagamiin~",
|
||||
"ymfm by Aaron Giles",
|
||||
"MAME SN76496 by Nicola Salmoria",
|
||||
"MAME AY-3-8910 by Couriersud",
|
||||
"with AY8930 fixes by Eulous, cam900 and Grauw",
|
||||
"MAME SAA1099 by Juergen Buchmueller and Manuel Abadia",
|
||||
"MAME Namco WSG by Nicola Salmoria and Aaron Giles",
|
||||
"MAME RF5C68 core by Olivier Galibert and Aaron Giles",
|
||||
"MAME MSM5232 core by Jarek Burczynski and Hiromitsu Shioya",
|
||||
"MAME MSM6258 core by Barry Rodewald",
|
||||
"MAME YMZ280B core by Aaron Giles",
|
||||
"MAME GA20 core by Acho A. Tang and R. Belmont",
|
||||
"MAME SegaPCM core by Hiromitsu Shioya and Olivier Galibert",
|
||||
"SAASound by Dave Hooper and Simon Owen",
|
||||
"SameBoy by Lior Halphon",
|
||||
"Mednafen PCE, WonderSwan, T6W28 and Virtual Boy audio cores",
|
||||
"SNES DSP core by Blargg",
|
||||
"puNES (NES, MMC5 and FDS) by FHorse",
|
||||
"NSFPlay (NES and FDS) by Brad Smith and Brezza",
|
||||
"reSID by Dag Lem",
|
||||
"reSIDfp by Dag Lem, Antti Lankila",
|
||||
"and Leandro Nini",
|
||||
"dSID by DefleMask Team based on jsSID",
|
||||
"Stella by Stella Team",
|
||||
"QSound emulator by superctr and Valley Bell",
|
||||
"VICE VIC-20 sound core by Rami Rasanen and viznut",
|
||||
"VICE TED sound core by Andreas Boose, Tibor Biczo",
|
||||
"and Marco van den Heuvel",
|
||||
"VERA sound core by Frank van den Hoef",
|
||||
"mzpokeysnd POKEY emulator by Michael Borisov",
|
||||
"ASAP POKEY emulator by Piotr Fusik",
|
||||
"ported by laoo to C++",
|
||||
"vgsound_emu (second version, modified version) by cam900",
|
||||
"SM8521 emulator (modified version) by cam900",
|
||||
"D65010G031 emulator (modified version) by cam900",
|
||||
"Namco C140/C219 emulator (modified version) by cam900",
|
||||
"PowerNoise emulator by scratchminer",
|
||||
"ep128emu by Istvan Varga",
|
||||
"NDS sound emulator by cam900",
|
||||
_N("Weak-JACK by x42"),
|
||||
_N("RtMidi by Gary P. Scavone"),
|
||||
_N("FFTW by Matteo Frigo and Steven G. Johnson"),
|
||||
_N("backward-cpp by Google"),
|
||||
_N("adpcm by superctr"),
|
||||
_N("adpcm-xq by David Bryant"),
|
||||
_N("Nuked-OPL3/OPLL/OPM/OPN2/PSG by nukeykt"),
|
||||
_N("YM3812-LLE, YMF262-LLE, YMF276-LLE and YM2608-LLE by nukeykt"),
|
||||
_N("ESFMu (modified version) by Kagamiin~"),
|
||||
_N("ymfm by Aaron Giles"),
|
||||
_N("emu2413 by Digital Sound Antiques"),
|
||||
_N("MAME SN76496 by Nicola Salmoria"),
|
||||
_N("MAME AY-3-8910 by Couriersud"),
|
||||
_N("with AY8930 fixes by Eulous, cam900 and Grauw"),
|
||||
_N("MAME SAA1099 by Juergen Buchmueller and Manuel Abadia"),
|
||||
_N("MAME Namco WSG by Nicola Salmoria and Aaron Giles"),
|
||||
_N("MAME RF5C68 core by Olivier Galibert and Aaron Giles"),
|
||||
_N("MAME MSM5232 core by Jarek Burczynski and Hiromitsu Shioya"),
|
||||
_N("MAME MSM6258 core by Barry Rodewald"),
|
||||
_N("MAME YMZ280B core by Aaron Giles"),
|
||||
_N("MAME GA20 core by Acho A. Tang and R. Belmont"),
|
||||
_N("MAME SegaPCM core by Hiromitsu Shioya and Olivier Galibert"),
|
||||
_N("SAASound by Dave Hooper and Simon Owen"),
|
||||
_N("SameBoy by Lior Halphon"),
|
||||
_N("Mednafen PCE, WonderSwan, T6W28 and Virtual Boy audio cores"),
|
||||
_N("SNES DSP core by Blargg"),
|
||||
_N("puNES (NES, MMC5 and FDS) by FHorse"),
|
||||
_N("NSFPlay (NES and FDS) by Brad Smith and Brezza"),
|
||||
_N("reSID by Dag Lem"),
|
||||
_N("reSIDfp by Dag Lem, Antti Lankila"),
|
||||
_N("and Leandro Nini"),
|
||||
_N("dSID by DefleMask Team based on jsSID"),
|
||||
_N("Stella by Stella Team"),
|
||||
_N("QSound emulator by superctr and Valley Bell"),
|
||||
_N("VICE VIC-20 sound core by Rami Rasanen and viznut"),
|
||||
_N("VICE TED sound core by Andreas Boose, Tibor Biczo"),
|
||||
_N("and Marco van den Heuvel"),
|
||||
_N("VERA sound core by Frank van den Hoef"),
|
||||
_N("mzpokeysnd POKEY emulator by Michael Borisov"),
|
||||
_N("ASAP POKEY emulator by Piotr Fusik"),
|
||||
_N("ported by laoo to C++"),
|
||||
_N("vgsound_emu (second version, modified version) by cam900"),
|
||||
_N("Impulse Tracker GUS volume table by Jeffrey Lim"),
|
||||
_N("Schism Tracker IT sample decompression"),
|
||||
_N("SM8521 emulator (modified version) by cam900"),
|
||||
_N("D65010G031 emulator (modified version) by cam900"),
|
||||
_N("Namco C140/C219 emulator (modified version) by cam900"),
|
||||
_N("PowerNoise emulator by scratchminer"),
|
||||
_N("ep128emu by Istvan Varga"),
|
||||
_N("NDS sound emulator by cam900"),
|
||||
"",
|
||||
"greetings to:",
|
||||
_N("greetings to:"),
|
||||
"NEOART Costa Rica",
|
||||
"Xenium Demoparty",
|
||||
"all members of Deflers of Noice!",
|
||||
"@party",
|
||||
_N("all members of Deflers of Noice!"),
|
||||
"",
|
||||
"copyright © 2021-2024 tildearrow",
|
||||
"(and contributors).",
|
||||
"licensed under GPLv2+! see",
|
||||
"LICENSE for more information.",
|
||||
_N("copyright © 2021-2024 tildearrow"),
|
||||
_N("(and contributors)."),
|
||||
_N("licensed under GPLv2+! see"),
|
||||
_N("LICENSE for more information."),
|
||||
"",
|
||||
"help Furnace grow:",
|
||||
_N("help Furnace grow:"),
|
||||
"https://github.com/tildearrow/furnace",
|
||||
"",
|
||||
"contact tildearrow at:",
|
||||
_N("contact tildearrow at:"),
|
||||
"https://tildearrow.org/?p=contact",
|
||||
"",
|
||||
"disclaimer:",
|
||||
"despite the fact this program works",
|
||||
"with the .dmf file format, it is NOT",
|
||||
"affiliated with Delek or DefleMask in",
|
||||
"any way, nor it is a replacement for",
|
||||
"the original program.",
|
||||
_N("disclaimer:"),
|
||||
_N("despite the fact this program works"),
|
||||
_N("with the .dmf file format, it is NOT"),
|
||||
_N("affiliated with Delek or DefleMask in"),
|
||||
_N("any way, nor it is a replacement for"),
|
||||
_N("the original program."),
|
||||
"",
|
||||
"it also comes with ABSOLUTELY NO WARRANTY.",
|
||||
_N("it also comes with ABSOLUTELY NO WARRANTY."),
|
||||
"",
|
||||
"thanks to all contributors/bug reporters!"
|
||||
_N("thanks to all contributors/bug reporters!")
|
||||
};
|
||||
|
||||
const size_t aboutCount=sizeof(aboutLine)/sizeof(aboutLine[0]);
|
||||
|
||||
void FurnaceGUI::drawAbout() {
|
||||
// do stuff
|
||||
if (ImGui::Begin("About Furnace",NULL,ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoDocking|ImGuiWindowFlags_NoTitleBar)) {
|
||||
if (ImGui::Begin("About Furnace",NULL,ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoDocking|ImGuiWindowFlags_NoTitleBar,_("About Furnace"))) {
|
||||
ImGui::SetWindowPos(ImVec2(0,0));
|
||||
ImGui::SetWindowSize(ImVec2(canvasW,canvasH));
|
||||
ImGui::PushFont(bigFont);
|
||||
|
|
@ -343,24 +387,26 @@ void FurnaceGUI::drawAbout() {
|
|||
}
|
||||
|
||||
for (size_t i=0; i<aboutCount; i++) {
|
||||
double posX=(canvasW/2.0)+(sin(double(i)*0.5+double(aboutScroll)/(90.0*dpiScale))*120*dpiScale)-(ImGui::CalcTextSize(aboutLine[i]).x*0.5);
|
||||
// don't localize tildearrow, the version or an empty line
|
||||
const char* nextLine=(i==0 || i==3 || aboutLine[i][0]==0)?aboutLine[i]:_(aboutLine[i]);
|
||||
double posX=(canvasW/2.0)+(sin(double(i)*0.5+double(aboutScroll)/(90.0*dpiScale))*120*dpiScale)-(ImGui::CalcTextSize(nextLine).x*0.5);
|
||||
double posY=(canvasH-aboutScroll+42*i*dpiScale);
|
||||
if (posY<-80*dpiScale || posY>canvasH) continue;
|
||||
dl->AddText(bigFont,bigFont->FontSize,
|
||||
ImVec2(posX+dpiScale,posY+dpiScale),
|
||||
0xff000000,aboutLine[i]);
|
||||
0xff000000,nextLine);
|
||||
dl->AddText(bigFont,bigFont->FontSize,
|
||||
ImVec2(posX+dpiScale,posY-dpiScale),
|
||||
0xff000000,aboutLine[i]);
|
||||
0xff000000,nextLine);
|
||||
dl->AddText(bigFont,bigFont->FontSize,
|
||||
ImVec2(posX-dpiScale,posY+dpiScale),
|
||||
0xff000000,aboutLine[i]);
|
||||
0xff000000,nextLine);
|
||||
dl->AddText(bigFont,bigFont->FontSize,
|
||||
ImVec2(posX-dpiScale,posY-dpiScale),
|
||||
0xff000000,aboutLine[i]);
|
||||
0xff000000,nextLine);
|
||||
dl->AddText(bigFont,bigFont->FontSize,
|
||||
ImVec2(posX,posY),
|
||||
0xffffffff,aboutLine[i]);
|
||||
0xffffffff,nextLine);
|
||||
}
|
||||
ImGui::PopFont();
|
||||
|
||||
|
|
@ -374,6 +420,16 @@ void FurnaceGUI::drawAbout() {
|
|||
while (aboutSin>=2400) aboutSin-=2400;
|
||||
if (aboutScroll>(42*dpiScale*aboutCount+canvasH)) aboutScroll=-20*dpiScale;
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_Space)) {
|
||||
aboutOpen=false;
|
||||
if (modified) {
|
||||
showWarning(_("Unsaved changes! Save changes before playing?"),GUI_WARN_CV);
|
||||
} else {
|
||||
cvOpen=true;
|
||||
cvNotSerious=true;
|
||||
}
|
||||
}
|
||||
|
||||
WAKE_UP;
|
||||
}
|
||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_ABOUT;
|
||||
|
|
|
|||
|
|
@ -29,23 +29,23 @@
|
|||
#define FURNACE_FFT_CUTOFF 0.1
|
||||
|
||||
const char* chanOscRefs[]={
|
||||
"None (0%)",
|
||||
"None (50%)",
|
||||
"None (100%)",
|
||||
_N("None (0%)"),
|
||||
_N("None (50%)"),
|
||||
_N("None (100%)"),
|
||||
|
||||
"Frequency",
|
||||
"Volume",
|
||||
"Channel",
|
||||
"Brightness",
|
||||
_N("Frequency"),
|
||||
_N("Volume"),
|
||||
_N("Channel"),
|
||||
_N("Brightness"),
|
||||
|
||||
"Note Trigger"
|
||||
_N("Note Trigger")
|
||||
};
|
||||
|
||||
const char* autoColsTypes[]={
|
||||
"Off",
|
||||
"Mode 1",
|
||||
"Mode 2",
|
||||
"Mode 3"
|
||||
_N("Off"),
|
||||
_N("Mode 1"),
|
||||
_N("Mode 2"),
|
||||
_N("Mode 3")
|
||||
};
|
||||
|
||||
static void _drawOsc(const ImDrawList* drawList, const ImDrawCmd* cmd) {
|
||||
|
|
@ -132,7 +132,7 @@ void FurnaceGUI::drawChanOsc() {
|
|||
}
|
||||
if (!chanOscOpen) return;
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(64.0f*dpiScale,32.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||
if (ImGui::Begin("Oscilloscope (per-channel)",&chanOscOpen,globalWinFlags)) {
|
||||
if (ImGui::Begin("Oscilloscope (per-channel)",&chanOscOpen,globalWinFlags,_("Oscilloscope (per-channel)"))) {
|
||||
bool centerSettingReset=false;
|
||||
ImDrawList* dl=ImGui::GetWindowDrawList();
|
||||
if (chanOscOptions) {
|
||||
|
|
@ -140,7 +140,7 @@ void FurnaceGUI::drawChanOsc() {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Columns");
|
||||
ImGui::Text(_("Columns"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputInt("##COSColumns",&chanOscCols,1,3)) {
|
||||
|
|
@ -149,7 +149,7 @@ void FurnaceGUI::drawChanOsc() {
|
|||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Size (ms)");
|
||||
ImGui::Text(_("Size (ms)"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputFloat("##COSWinSize",&chanOscWindowSize,1.0f,10.0f)) {
|
||||
|
|
@ -160,7 +160,7 @@ void FurnaceGUI::drawChanOsc() {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Automatic columns");
|
||||
ImGui::Text(_("Automatic columns"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
const char* previewColType=autoColsTypes[chanOscAutoColsType&3];
|
||||
|
|
@ -174,19 +174,19 @@ void FurnaceGUI::drawChanOsc() {
|
|||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Checkbox("Center waveform",&chanOscWaveCorr)) {
|
||||
if (ImGui::Checkbox(_("Center waveform"),&chanOscWaveCorr)) {
|
||||
centerSettingReset=true;
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Checkbox("Randomize phase on note",&chanOscRandomPhase)) {
|
||||
if (ImGui::Checkbox(_("Randomize phase on note"),&chanOscRandomPhase)) {
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Amplitude");
|
||||
ImGui::Text(_("Amplitude"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (CWSliderFloat("##COSAmp",&chanOscAmplify,0.0f,2.0f)) {
|
||||
|
|
@ -196,7 +196,7 @@ void FurnaceGUI::drawChanOsc() {
|
|||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Line size");
|
||||
ImGui::Text(_("Line size"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (CWSliderFloat("##COSLine",&chanOscLineSize,0.25f,16.0f)) {
|
||||
|
|
@ -208,14 +208,14 @@ void FurnaceGUI::drawChanOsc() {
|
|||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Gradient",&chanOscUseGrad);
|
||||
ImGui::Checkbox(_("Gradient"),&chanOscUseGrad);
|
||||
|
||||
if (chanOscUseGrad) {
|
||||
if (chanOscGradTex==NULL) {
|
||||
chanOscGradTex=rend->createTexture(true,chanOscGrad.width,chanOscGrad.height);
|
||||
chanOscGradTex=rend->createTexture(true,chanOscGrad.width,chanOscGrad.height,true,bestTexFormat);
|
||||
|
||||
if (chanOscGradTex==NULL) {
|
||||
logE("error while creating gradient texture!");
|
||||
logE(_("error while creating gradient texture!"));
|
||||
} else {
|
||||
updateChanOscGradTex=true;
|
||||
}
|
||||
|
|
@ -233,13 +233,13 @@ void FurnaceGUI::drawChanOsc() {
|
|||
if (rend->updateTexture(chanOscGradTex,chanOscGrad.grad.get(),chanOscGrad.width*4)) {
|
||||
updateChanOscGradTex=false;
|
||||
} else {
|
||||
logE("error while updating gradient texture!");
|
||||
logE(_("error while updating gradient texture!"));
|
||||
}
|
||||
}
|
||||
|
||||
ImVec2 gradLeft=ImGui::GetCursorPos();
|
||||
ImVec2 gradSize=ImVec2(400.0f*dpiScale,400.0f*dpiScale);
|
||||
ImGui::Image(rend->getTextureID(chanOscGradTex),gradSize);
|
||||
ImGui::Image(rend->getTextureID(chanOscGradTex),gradSize,ImVec2(0,0),ImVec2(rend->getTextureU(chanOscGradTex),rend->getTextureV(chanOscGradTex)));
|
||||
ImVec2 gradLeftAbs=ImGui::GetItemRectMin();
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
|
||||
if (chanOscGrad.points.size()<32) {
|
||||
|
|
@ -289,11 +289,11 @@ void FurnaceGUI::drawChanOsc() {
|
|||
i.prevY=i.y;
|
||||
}
|
||||
if (ImGui::BeginPopup("gradPointSettings",ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
if (ImGui::ColorPicker4("Color",(float*)&i.color)) {
|
||||
if (ImGui::ColorPicker4(_("Color"),(float*)&i.color)) {
|
||||
updateChanOscGradTex=true;
|
||||
}
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Distance");
|
||||
ImGui::Text(_("Distance"));
|
||||
ImGui::SameLine();
|
||||
float pDist=i.distance*100.0f;
|
||||
if (ImGui::SliderFloat("##PDistance",&pDist,0.0f,150.0f,"%.1f%%")) {
|
||||
|
|
@ -302,7 +302,7 @@ void FurnaceGUI::drawChanOsc() {
|
|||
}
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Spread");
|
||||
ImGui::Text(_("Spread"));
|
||||
ImGui::SameLine();
|
||||
float pSpread=i.spread*100.0f;
|
||||
if (ImGui::SliderFloat("##PSpread",&pSpread,0.0f,150.0f,"%.1f%%")) {
|
||||
|
|
@ -311,7 +311,7 @@ void FurnaceGUI::drawChanOsc() {
|
|||
}
|
||||
|
||||
pushDestColor();
|
||||
if (ImGui::Button("Remove")) {
|
||||
if (ImGui::Button(_("Remove"))) {
|
||||
removePoint=index;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
|
@ -335,26 +335,26 @@ void FurnaceGUI::drawChanOsc() {
|
|||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::ColorEdit4("Background",(float*)&chanOscGrad.bgColor)) {
|
||||
if (ImGui::ColorEdit4(_("Background"),(float*)&chanOscGrad.bgColor)) {
|
||||
updateChanOscGradTex=true;
|
||||
}
|
||||
ImGui::Combo("X Axis##AxisX",&chanOscColorX,chanOscRefs,GUI_OSCREF_MAX);
|
||||
ImGui::Combo("Y Axis##AxisY",&chanOscColorY,chanOscRefs,GUI_OSCREF_MAX);
|
||||
ImGui::Combo(_("X Axis##AxisX"),&chanOscColorX,LocalizedComboGetter,chanOscRefs,GUI_OSCREF_MAX);
|
||||
ImGui::Combo(_("Y Axis##AxisY"),&chanOscColorY,LocalizedComboGetter,chanOscRefs,GUI_OSCREF_MAX);
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
} else {
|
||||
ImGui::SetNextItemWidth(400.0f*dpiScale);
|
||||
ImGui::ColorPicker4("Color",(float*)&chanOscColor);
|
||||
ImGui::ColorPicker4(_("Color"),(float*)&chanOscColor);
|
||||
}
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Text format:");
|
||||
ImGui::Text(_("Text format:"));
|
||||
ImGui::SameLine();
|
||||
ImGui::InputText("##TextFormat",&chanOscTextFormat);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
if (ImGui::BeginTooltip()) {
|
||||
ImGui::TextUnformatted(
|
||||
ImGui::TextUnformatted(_(
|
||||
"format guide:\n"
|
||||
"- %c: channel name\n"
|
||||
"- %C: channel short name\n"
|
||||
|
|
@ -372,14 +372,14 @@ void FurnaceGUI::drawChanOsc() {
|
|||
"- %b: volume (hex)\n"
|
||||
"- %l: new line\n"
|
||||
"- %%: percent sign"
|
||||
);
|
||||
));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::ColorEdit4("Text color",(float*)&chanOscTextColor);
|
||||
ImGui::ColorEdit4(_("Text color"),(float*)&chanOscTextColor);
|
||||
|
||||
if (ImGui::Button("OK")) {
|
||||
if (ImGui::Button(_("OK"))) {
|
||||
chanOscOptions=false;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -397,7 +397,7 @@ void FurnaceGUI::drawChanOsc() {
|
|||
|
||||
// check work thread
|
||||
if (chanOscWorkPool==NULL) {
|
||||
logV("creating chan osc work pool");
|
||||
logV(_("creating chan osc work pool"));
|
||||
chanOscWorkPool=new DivWorkPool(settings.chanOscThreads);
|
||||
}
|
||||
|
||||
|
|
@ -426,18 +426,18 @@ void FurnaceGUI::drawChanOsc() {
|
|||
|
||||
// check FFT status existence
|
||||
if (!fft_->ready) {
|
||||
logD("creating FFT plan for channel %d",fft_->relatedCh);
|
||||
logD(_("creating FFT plan for channel %d"),fft_->relatedCh);
|
||||
fft_->inBuf=(double*)fftw_malloc(FURNACE_FFT_SIZE*sizeof(double));
|
||||
fft_->outBuf=(fftw_complex*)fftw_malloc(FURNACE_FFT_SIZE*sizeof(fftw_complex));
|
||||
fft_->corrBuf=(double*)fftw_malloc(FURNACE_FFT_SIZE*sizeof(double));
|
||||
fft_->plan=fftw_plan_dft_r2c_1d(FURNACE_FFT_SIZE,fft_->inBuf,fft_->outBuf,FFTW_ESTIMATE);
|
||||
fft_->planI=fftw_plan_dft_c2r_1d(FURNACE_FFT_SIZE,fft_->outBuf,fft_->corrBuf,FFTW_ESTIMATE);
|
||||
if (fft_->plan==NULL) {
|
||||
logE("failed to create plan!");
|
||||
logE(_("failed to create plan!"));
|
||||
} else if (fft_->planI==NULL) {
|
||||
logE("failed to create inverse plan!");
|
||||
logE(_("failed to create inverse plan!"));
|
||||
} else if (fft_->inBuf==NULL || fft_->outBuf==NULL || fft_->corrBuf==NULL) {
|
||||
logE("failed to create FFT buffers");
|
||||
logE(_("failed to create FFT buffers"));
|
||||
} else {
|
||||
fft_->ready=true;
|
||||
}
|
||||
|
|
@ -582,7 +582,7 @@ void FurnaceGUI::drawChanOsc() {
|
|||
ChanOscStatus* fft=oscFFTs[i];
|
||||
int ch=oscChans[i];
|
||||
if (buf==NULL) {
|
||||
ImGui::Text("Error!");
|
||||
ImGui::Text(_("Error!"));
|
||||
} else {
|
||||
ImVec2 size=ImGui::GetContentRegionAvail();
|
||||
size.y=availY/rows;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ void FurnaceGUI::drawChannels() {
|
|||
} else {
|
||||
//ImGui::SetNextWindowSizeConstraints(ImVec2(440.0f*dpiScale,400.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||
}
|
||||
if (ImGui::Begin("Channels",&channelsOpen,globalWinFlags)) {
|
||||
if (ImGui::Begin("Channels",&channelsOpen,globalWinFlags,_("Channels"))) {
|
||||
if (ImGui::BeginTable("ChannelList",5)) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,0.0);
|
||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,0.0);
|
||||
|
|
@ -46,13 +46,13 @@ void FurnaceGUI::drawChannels() {
|
|||
ImGui::TableSetupColumn("c4",ImGuiTableColumnFlags_WidthFixed,48.0f*dpiScale);
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Pat");
|
||||
ImGui::Text(_("Pat"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Osc");
|
||||
ImGui::Text(_("Osc"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Swap");
|
||||
ImGui::Text(_("Swap"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Name");
|
||||
ImGui::Text(_("Name"));
|
||||
for (int i=0; i<e->getTotalChannelCount(); i++) {
|
||||
ImGui::PushID(i);
|
||||
ImGui::TableNextRow();
|
||||
|
|
@ -61,14 +61,14 @@ void FurnaceGUI::drawChannels() {
|
|||
MARK_MODIFIED;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Show in pattern");
|
||||
ImGui::SetTooltip(_("Show in pattern"));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Checkbox("##VisibleChanOsc",&e->curSubSong->chanShowChanOsc[i])) {
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Show in per-channel oscilloscope");
|
||||
ImGui::SetTooltip(_("Show in per-channel oscilloscope"));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button(ICON_FA_ARROWS)) {
|
||||
|
|
@ -79,7 +79,7 @@ void FurnaceGUI::drawChannels() {
|
|||
ImGui::Button(ICON_FA_ARROWS "##ChanDrag");
|
||||
ImGui::EndDragDropSource();
|
||||
} else if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("%s #%d\n(drag to swap channels)",e->getSystemName(e->sysOfChan[i]),e->dispatchChanOfChan[i]);
|
||||
ImGui::SetTooltip(_("%s #%d\n(drag to swap channels)"),e->getSystemName(e->sysOfChan[i]),e->dispatchChanOfChan[i]);
|
||||
}
|
||||
if (ImGui::BeginDragDropTarget()) {
|
||||
const ImGuiPayload* dragItem=ImGui::AcceptDragDropPayload("FUR_CHAN");
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ void FurnaceGUI::drawClock() {
|
|||
nextWindow=GUI_WINDOW_NOTHING;
|
||||
}
|
||||
if (!clockOpen) return;
|
||||
if (ImGui::Begin("Clock",&clockOpen,globalWinFlags)) {
|
||||
if (ImGui::Begin("Clock",&clockOpen,globalWinFlags,_("Clock"))) {
|
||||
int row=oldRow;
|
||||
int elapsedBars=e->getElapsedBars();
|
||||
int elapsedBeats=e->getElapsedBeats();
|
||||
|
|
|
|||
|
|
@ -48,22 +48,22 @@ void FurnaceGUI::drawPalette() {
|
|||
int width=ImGui::GetContentRegionAvail().x;
|
||||
ImGui::SetNextItemWidth(width);
|
||||
|
||||
const char* hint="Search...";
|
||||
const char* hint=_("Search...");
|
||||
switch (curPaletteType) {
|
||||
case CMDPAL_TYPE_RECENT:
|
||||
hint="Search recent files...";
|
||||
hint=_("Search recent files...");
|
||||
break;
|
||||
case CMDPAL_TYPE_INSTRUMENTS:
|
||||
hint="Search instruments...";
|
||||
hint=_("Search instruments...");
|
||||
break;
|
||||
case CMDPAL_TYPE_SAMPLES:
|
||||
hint="Search samples...";
|
||||
hint=_("Search samples...");
|
||||
break;
|
||||
case CMDPAL_TYPE_INSTRUMENT_CHANGE:
|
||||
hint="Search instruments (to change to)...";
|
||||
hint=_("Search instruments (to change to)...");
|
||||
break;
|
||||
case CMDPAL_TYPE_ADD_CHIP:
|
||||
hint="Search chip (to add)...";
|
||||
hint=_("Search chip (to add)...");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ void FurnaceGUI::drawPalette() {
|
|||
|
||||
case CMDPAL_TYPE_INSTRUMENTS:
|
||||
case CMDPAL_TYPE_INSTRUMENT_CHANGE:
|
||||
if (matchFuzzy("- None -",paletteQuery.c_str())) {
|
||||
if (matchFuzzy(_("- None -"),paletteQuery.c_str())) {
|
||||
paletteSearchResults.push_back(0);
|
||||
}
|
||||
for (int i=0; i<e->song.insLen; i++) {
|
||||
|
|
@ -120,7 +120,7 @@ void FurnaceGUI::drawPalette() {
|
|||
break;
|
||||
|
||||
default:
|
||||
logE("invalid command palette type");
|
||||
logE(_("invalid command palette type"));
|
||||
ImGui::CloseCurrentPopup();
|
||||
break;
|
||||
};
|
||||
|
|
@ -164,7 +164,7 @@ void FurnaceGUI::drawPalette() {
|
|||
case CMDPAL_TYPE_INSTRUMENTS:
|
||||
case CMDPAL_TYPE_INSTRUMENT_CHANGE:
|
||||
if (id==0) {
|
||||
s="- None -";
|
||||
s=_("- None -");
|
||||
} else {
|
||||
s=fmt::sprintf("%02X: %s", id-1, e->song.ins[id-1]->name.c_str());
|
||||
}
|
||||
|
|
@ -176,7 +176,7 @@ void FurnaceGUI::drawPalette() {
|
|||
s=getSystemName((DivSystem)id);
|
||||
break;
|
||||
default:
|
||||
logE("invalid command palette type");
|
||||
logE(_("invalid command palette type"));
|
||||
break;
|
||||
};
|
||||
|
||||
|
|
@ -196,7 +196,7 @@ void FurnaceGUI::drawPalette() {
|
|||
accepted=ImGui::IsKeyPressed(ImGuiKey_Enter);
|
||||
}
|
||||
|
||||
if (ImGui::Button("Cancel") || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
if (ImGui::Button(_("Cancel")) || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
|
|
@ -238,7 +238,7 @@ void FurnaceGUI::drawPalette() {
|
|||
}
|
||||
break;
|
||||
default:
|
||||
logE("invalid command palette type");
|
||||
logE(_("invalid command palette type"));
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,321 +28,325 @@ void FurnaceGUI::drawCompatFlags() {
|
|||
nextWindow=GUI_WINDOW_NOTHING;
|
||||
}
|
||||
if (!compatFlagsOpen) return;
|
||||
if (ImGui::Begin("Compatibility Flags",&compatFlagsOpen,globalWinFlags)) {
|
||||
ImGui::TextWrapped("these flags are designed to provide better DefleMask/older Furnace compatibility.\nit is recommended to disable most of these unless you rely on specific quirks.");
|
||||
if (ImGui::Begin("Compatibility Flags",&compatFlagsOpen,globalWinFlags,_("Compatibility Flags"))) {
|
||||
ImGui::TextWrapped(_("these flags are designed to provide better DefleMask/older Furnace compatibility.\nit is recommended to disable most of these unless you rely on specific quirks."));
|
||||
if (ImGui::BeginTabBar("settingsTab")) {
|
||||
if (ImGui::BeginTabItem("DefleMask")) {
|
||||
ImGui::Checkbox("Limit slide range",&e->song.limitSlides);
|
||||
if (ImGui::BeginTabItem(_("DefleMask"))) {
|
||||
ImGui::Checkbox(_("Limit slide range"),&e->song.limitSlides);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("when enabled, slides are limited to a compatible range.\nmay cause problems with slides in negative octaves.");
|
||||
ImGui::SetTooltip(_("when enabled, slides are limited to a compatible range.\nmay cause problems with slides in negative octaves."));
|
||||
}
|
||||
InvCheckbox("Compatible noise layout on NES and PC Engine",&e->song.properNoiseLayout);
|
||||
InvCheckbox(_("Compatible noise layout on NES and PC Engine"),&e->song.properNoiseLayout);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("use a rather unusual compatible noise frequency layout.\nremoves some noise frequencies on PC Engine.");
|
||||
ImGui::SetTooltip(_("use a rather unusual compatible noise frequency layout.\nremoves some noise frequencies on PC Engine."));
|
||||
}
|
||||
ImGui::Checkbox("Game Boy instrument duty is wave volume",&e->song.waveDutyIsVol);
|
||||
ImGui::Checkbox(_("Game Boy instrument duty is wave volume"),&e->song.waveDutyIsVol);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("if enabled, an instrument with duty macro in the wave channel will be mapped to wavetable volume.");
|
||||
ImGui::SetTooltip(_("if enabled, an instrument with duty macro in the wave channel will be mapped to wavetable volume."));
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Restart macro on portamento",&e->song.resetMacroOnPorta);
|
||||
ImGui::Checkbox(_("Restart macro on portamento"),&e->song.resetMacroOnPorta);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("when enabled, a portamento effect will reset the channel's macro if used in combination with a note.");
|
||||
ImGui::SetTooltip(_("when enabled, a portamento effect will reset the channel's macro if used in combination with a note."));
|
||||
}
|
||||
ImGui::Checkbox("Legacy volume slides",&e->song.legacyVolumeSlides);
|
||||
ImGui::Checkbox(_("Legacy volume slides"),&e->song.legacyVolumeSlides);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("simulate glitchy volume slide behavior by silently overflowing the volume when the slide goes below 0.");
|
||||
ImGui::SetTooltip(_("simulate glitchy volume slide behavior by silently overflowing the volume when the slide goes below 0."));
|
||||
}
|
||||
ImGui::Checkbox("Compatible arpeggio",&e->song.compatibleArpeggio);
|
||||
ImGui::Checkbox(_("Compatible arpeggio"),&e->song.compatibleArpeggio);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("delay arpeggio by one tick on every new note.");
|
||||
ImGui::SetTooltip(_("delay arpeggio by one tick on every new note."));
|
||||
}
|
||||
ImGui::Checkbox("Disable DAC when sample ends",&e->song.brokenDACMode);
|
||||
ImGui::Checkbox(_("Disable DAC when sample ends"),&e->song.brokenDACMode);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("when enabled, the DAC in YM2612 will be disabled if there isn't any sample playing.");
|
||||
ImGui::SetTooltip(_("when enabled, the DAC in YM2612 will be disabled if there isn't any sample playing."));
|
||||
}
|
||||
ImGui::Checkbox("Broken speed alternation",&e->song.brokenSpeedSel);
|
||||
ImGui::Checkbox(_("Broken speed alternation"),&e->song.brokenSpeedSel);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("determines next speed based on whether the row is odd/even instead of alternating between speeds.");
|
||||
ImGui::SetTooltip(_("determines next speed based on whether the row is odd/even instead of alternating between speeds."));
|
||||
}
|
||||
ImGui::Checkbox("Ignore duplicate slide effects",&e->song.ignoreDuplicateSlides);
|
||||
ImGui::Checkbox(_("Ignore duplicate slide effects"),&e->song.ignoreDuplicateSlides);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("if this is on, only the first slide of a row in a channel will be considered.");
|
||||
ImGui::SetTooltip(_("if this is on, only the first slide of a row in a channel will be considered."));
|
||||
}
|
||||
ImGui::Checkbox("Ignore 0Dxx on the last order",&e->song.ignoreJumpAtEnd);
|
||||
ImGui::Checkbox(_("Ignore 0Dxx on the last order"),&e->song.ignoreJumpAtEnd);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("if this is on, a jump to next row effect will not take place when it is on the last order of a song.");
|
||||
ImGui::SetTooltip(_("if this is on, a jump to next row effect will not take place when it is on the last order of a song."));
|
||||
}
|
||||
ImGui::Checkbox("Buggy portamento after pitch slide",&e->song.buggyPortaAfterSlide);
|
||||
ImGui::Checkbox(_("Buggy portamento after pitch slide"),&e->song.buggyPortaAfterSlide);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("simulates a bug in where portamento does not work after sliding.");
|
||||
ImGui::SetTooltip(_("simulates a bug in where portamento does not work after sliding."));
|
||||
}
|
||||
ImGui::Checkbox("FM pitch slide octave boundary odd behavior",&e->song.fbPortaPause);
|
||||
ImGui::Checkbox(_("FM pitch slide octave boundary odd behavior"),&e->song.fbPortaPause);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("if this is on, a pitch slide that crosses the octave boundary will stop for one tick and then continue from the nearest octave boundary.\nfor .dmf compatibility.");
|
||||
ImGui::SetTooltip(_("if this is on, a pitch slide that crosses the octave boundary will stop for one tick and then continue from the nearest octave boundary.\nfor .dmf compatibility."));
|
||||
}
|
||||
InvCheckbox("Don't apply Game Boy envelope on note-less instrument change",&e->song.gbInsAffectsEnvelope);
|
||||
InvCheckbox(_("Don't apply Game Boy envelope on note-less instrument change"),&e->song.gbInsAffectsEnvelope);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("if this is on, an instrument change will not affect the envelope.");
|
||||
ImGui::SetTooltip(_("if this is on, an instrument change will not affect the envelope."));
|
||||
}
|
||||
ImGui::Checkbox("Ignore DAC mode change outside of intended channel in ExtCh mode",&e->song.ignoreDACModeOutsideIntendedChannel);
|
||||
ImGui::Checkbox(_("Ignore DAC mode change outside of intended channel in ExtCh mode"),&e->song.ignoreDACModeOutsideIntendedChannel);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("if this is on, 17xx has no effect on the operator channels in YM2612.");
|
||||
ImGui::SetTooltip(_("if this is on, 17xx has no effect on the operator channels in YM2612."));
|
||||
}
|
||||
ImGui::Checkbox("E1xy/E2xy also take priority over slide stops",&e->song.e1e2AlsoTakePriority);
|
||||
ImGui::Checkbox(_("E1xy/E2xy also take priority over slide stops"),&e->song.e1e2AlsoTakePriority);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("does this make any sense by now?");
|
||||
ImGui::SetTooltip(_("does this make any sense by now?"));
|
||||
}
|
||||
ImGui::Checkbox("E1xy/E2xy stop when repeating the same note",&e->song.e1e2StopOnSameNote);
|
||||
ImGui::Checkbox(_("E1xy/E2xy stop when repeating the same note"),&e->song.e1e2StopOnSameNote);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("ugh, if only this wasn't a thing...");
|
||||
ImGui::SetTooltip(_("ugh, if only this wasn't a thing..."));
|
||||
}
|
||||
ImGui::Checkbox("SN76489 duty macro always resets phase",&e->song.snDutyReset);
|
||||
ImGui::Checkbox(_("SN76489 duty macro always resets phase"),&e->song.snDutyReset);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("when enabled, duty macro will always reset phase, even if its value hasn't changed.");
|
||||
ImGui::SetTooltip(_("when enabled, duty macro will always reset phase, even if its value hasn't changed."));
|
||||
}
|
||||
InvCheckbox("Broken volume scaling strategy",&e->song.newVolumeScaling);
|
||||
InvCheckbox(_("Broken volume scaling strategy"),&e->song.newVolumeScaling);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("when enabled:\n- log scaling: multiply\n- linear scaling: subtract\nwhen disabled:\n- log scaling: subtract\n- linear scaling: multiply");
|
||||
ImGui::SetTooltip(_("when enabled:\n- log scaling: multiply\n- linear scaling: subtract\nwhen disabled:\n- log scaling: subtract\n- linear scaling: multiply"));
|
||||
}
|
||||
InvCheckbox("Don't persist volume macro after it finishes",&e->song.volMacroLinger);
|
||||
InvCheckbox(_("Don't persist volume macro after it finishes"),&e->song.volMacroLinger);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("when enabled, a value in the volume column that happens after the volume macro is done will disregard the macro.");
|
||||
ImGui::SetTooltip(_("when enabled, a value in the volume column that happens after the volume macro is done will disregard the macro."));
|
||||
}
|
||||
ImGui::Checkbox("Broken output volume on instrument change",&e->song.brokenOutVol);
|
||||
ImGui::Checkbox(_("Broken output volume on instrument change"),&e->song.brokenOutVol);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("if enabled, no checks for the presence of a volume macro will be made.\nthis will cause the last macro value to linger unless a value in the volume column is present.");
|
||||
ImGui::SetTooltip(_("if enabled, no checks for the presence of a volume macro will be made.\nthis will cause the last macro value to linger unless a value in the volume column is present."));
|
||||
}
|
||||
ImGui::Checkbox("Broken output volume - Episode 2 (PLEASE KEEP ME DISABLED)",&e->song.brokenOutVol2);
|
||||
ImGui::Checkbox(_("Broken output volume - Episode 2 (PLEASE KEEP ME DISABLED)"),&e->song.brokenOutVol2);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("these compatibility flags are getting SO damn ridiculous and out of control.\nas you may have guessed, this one exists due to yet ANOTHER DefleMask-specific behavior.\nplease keep this off at all costs, because I will not support it when ROM export comes.\noh, and don't start an argument out of it. Furnace isn't a DefleMask replacement, and no,\nI am not trying to make it look like one with all these flags.\n\noh, and what about the other flags that don't have to do with DefleMask?\nthose are for .mod import, future FamiTracker import and personal taste!\n\nend of rant");
|
||||
ImGui::SetTooltip(_("these compatibility flags are getting SO damn ridiculous and out of control.\nas you may have guessed, this one exists due to yet ANOTHER DefleMask-specific behavior.\nplease keep this off at all costs, because I will not support it when ROM export comes.\noh, and don't start an argument out of it. Furnace isn't a DefleMask replacement, and no,\nI am not trying to make it look like one with all these flags.\n\noh, and what about the other flags that don't have to do with DefleMask?\nthose are for .mod import, future FamiTracker import and personal taste!\n\nend of rant"));
|
||||
}
|
||||
ImGui::Checkbox("Treat SN76489 periods under 8 as 1",&e->song.snNoLowPeriods);
|
||||
ImGui::Checkbox(_("Treat SN76489 periods under 8 as 1"),&e->song.snNoLowPeriods);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("when enabled, any SN period under 8 will be written as 1 instead.\nthis replicates DefleMask behavior, but reduces available period range.");
|
||||
ImGui::SetTooltip(_("when enabled, any SN period under 8 will be written as 1 instead.\nthis replicates DefleMask behavior, but reduces available period range."));
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Old Furnace")) {
|
||||
ImGui::Checkbox("Arpeggio inhibits non-porta slides",&e->song.arpNonPorta);
|
||||
if (ImGui::BeginTabItem(_("Old Furnace"))) {
|
||||
ImGui::Checkbox(_("Arpeggio inhibits non-porta slides"),&e->song.arpNonPorta);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.5.5");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.5.5"));
|
||||
}
|
||||
ImGui::Checkbox("Wack FM algorithm macro",&e->song.algMacroBehavior);
|
||||
ImGui::Checkbox(_("Wack FM algorithm macro"),&e->song.algMacroBehavior);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.5.5");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.5.5"));
|
||||
}
|
||||
ImGui::Checkbox("Broken shortcut slides (E1xy/E2xy)",&e->song.brokenShortcutSlides);
|
||||
ImGui::Checkbox(_("Broken shortcut slides (E1xy/E2xy)"),&e->song.brokenShortcutSlides);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.5.7");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.5.7"));
|
||||
}
|
||||
ImGui::Checkbox("Stop portamento on note off",&e->song.stopPortaOnNoteOff);
|
||||
ImGui::Checkbox(_("Stop portamento on note off"),&e->song.stopPortaOnNoteOff);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6pre1");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.6pre1"));
|
||||
}
|
||||
InvCheckbox("Don't allow instrument change during slides",&e->song.newInsTriggersInPorta);
|
||||
InvCheckbox(_("Don't allow instrument change during slides"),&e->song.newInsTriggersInPorta);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6pre1");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.6pre1"));
|
||||
}
|
||||
InvCheckbox("Don't reset note to base on arpeggio stop",&e->song.arp0Reset);
|
||||
InvCheckbox(_("Don't reset note to base on arpeggio stop"),&e->song.arp0Reset);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6pre1");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.6pre1"));
|
||||
}
|
||||
InvCheckbox("ExtCh channel status is not shared among operators",&e->song.sharedExtStat);
|
||||
InvCheckbox(_("ExtCh channel status is not shared among operators"),&e->song.sharedExtStat);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6pre1");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.6pre1"));
|
||||
}
|
||||
InvCheckbox("Disable new SegaPCM features (macros and better panning)",&e->song.newSegaPCM);
|
||||
InvCheckbox(_("Disable new SegaPCM features (macros and better panning)"),&e->song.newSegaPCM);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6pre1");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.6pre1"));
|
||||
}
|
||||
ImGui::Checkbox("Old FM octave boundary behavior",&e->song.oldOctaveBoundary);
|
||||
ImGui::Checkbox(_("Old FM octave boundary behavior"),&e->song.oldOctaveBoundary);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6pre1");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.6pre1"));
|
||||
}
|
||||
ImGui::Checkbox("Disable OPN2 DAC volume control",&e->song.noOPN2Vol);
|
||||
ImGui::Checkbox(_("Disable OPN2 DAC volume control"),&e->song.noOPN2Vol);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6pre1");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.6pre1"));
|
||||
}
|
||||
ImGui::Checkbox("Broken initial position of portamento after arpeggio",&e->song.brokenPortaArp);
|
||||
ImGui::Checkbox(_("Broken initial position of portamento after arpeggio"),&e->song.brokenPortaArp);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6pre1.5");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.6pre1.5"));
|
||||
}
|
||||
ImGui::Checkbox("Disable new sample features",&e->song.disableSampleMacro);
|
||||
ImGui::Checkbox(_("Disable new sample features"),&e->song.disableSampleMacro);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6pre2");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.6pre2"));
|
||||
}
|
||||
ImGui::Checkbox("Old arpeggio macro + pitch slide strategy",&e->song.oldArpStrategy);
|
||||
ImGui::Checkbox(_("Old arpeggio macro + pitch slide strategy"),&e->song.oldArpStrategy);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6pre2");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.6pre2"));
|
||||
}
|
||||
ImGui::Checkbox("Broken portamento during legato",&e->song.brokenPortaLegato);
|
||||
ImGui::Checkbox(_("Broken portamento during legato"),&e->song.brokenPortaLegato);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6pre4");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.6pre4"));
|
||||
}
|
||||
ImGui::Checkbox("Broken macros in some FM chips after note off",&e->song.brokenFMOff);
|
||||
ImGui::Checkbox(_("Broken macros in some FM chips after note off"),&e->song.brokenFMOff);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6pre5");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.6pre5"));
|
||||
}
|
||||
ImGui::Checkbox("Pre-note does not take effects into consideration",&e->song.preNoteNoEffect);
|
||||
ImGui::Checkbox(_("Pre-note does not take effects into consideration"),&e->song.preNoteNoEffect);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6pre9");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.6pre9"));
|
||||
}
|
||||
ImGui::Checkbox("Disable new NES DPCM features",&e->song.oldDPCM);
|
||||
ImGui::Checkbox(_("Disable new NES DPCM features"),&e->song.oldDPCM);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6.1");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.6.1"));
|
||||
}
|
||||
ImGui::Checkbox("Legacy technical ALWAYS_SET_VOLUME behavior",&e->song.oldAlwaysSetVolume);
|
||||
ImGui::Checkbox(_("Legacy technical ALWAYS_SET_VOLUME behavior"),&e->song.oldAlwaysSetVolume);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6.1\nthis flag will be removed if I find out that none of the songs break after disabling it.");
|
||||
ImGui::SetTooltip(_("behavior changed in 0.6.1\nthis flag will be removed if I find out that none of the songs break after disabling it."));
|
||||
}
|
||||
ImGui::Checkbox(_("Old sample offset effect"),&e->song.oldSampleOffset);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip(_("behavior changed in 0.6.3"));
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem(".mod import")) {
|
||||
ImGui::Checkbox("Don't slide on the first tick of a row",&e->song.noSlidesOnFirstTick);
|
||||
if (ImGui::BeginTabItem(_(".mod import"))) {
|
||||
ImGui::Checkbox(_("Don't slide on the first tick of a row"),&e->song.noSlidesOnFirstTick);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("simulates ProTracker's behavior of not applying volume/pitch slides on the first tick of a row.");
|
||||
ImGui::SetTooltip(_("simulates ProTracker's behavior of not applying volume/pitch slides on the first tick of a row."));
|
||||
}
|
||||
ImGui::Checkbox("Reset arpeggio position on row change",&e->song.rowResetsArpPos);
|
||||
ImGui::Checkbox(_("Reset arpeggio position on row change"),&e->song.rowResetsArpPos);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("simulates ProTracker's behavior of arpeggio being bound to the current tick of a row.");
|
||||
ImGui::SetTooltip(_("simulates ProTracker's behavior of arpeggio being bound to the current tick of a row."));
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Pitch/Playback")) {
|
||||
ImGui::Text("Pitch linearity:");
|
||||
if (ImGui::BeginTabItem(_("Pitch/Playback"))) {
|
||||
ImGui::Text(_("Pitch linearity:"));
|
||||
ImGui::Indent();
|
||||
if (ImGui::RadioButton("None",e->song.linearPitch==0)) {
|
||||
if (ImGui::RadioButton(_("None"),e->song.linearPitch==0)) {
|
||||
e->song.linearPitch=0;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("like ProTracker/FamiTracker");
|
||||
ImGui::SetTooltip(_("like ProTracker/FamiTracker"));
|
||||
}
|
||||
if (e->song.linearPitch==1) {
|
||||
pushWarningColor(true);
|
||||
if (ImGui::RadioButton("Partial (only 04xy/E5xx)",e->song.linearPitch==1)) {
|
||||
if (ImGui::RadioButton(_("Partial (only 04xy/E5xx)"),e->song.linearPitch==1)) {
|
||||
e->song.linearPitch=1;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("like DefleMask\n\nthis pitch linearity mode is deprecated due to:\n- excessive complexity\n- lack of possible optimization\n\nit is recommended to change it now because I will remove this option in the future!");
|
||||
ImGui::SetTooltip(_("like DefleMask\n\nthis pitch linearity mode is deprecated due to:\n- excessive complexity\n- lack of possible optimization\n\nit is recommended to change it now because I will remove this option in the future!"));
|
||||
}
|
||||
popWarningColor();
|
||||
}
|
||||
if (ImGui::RadioButton("Full",e->song.linearPitch==2)) {
|
||||
if (ImGui::RadioButton(_("Full"),e->song.linearPitch==2)) {
|
||||
e->song.linearPitch=2;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("like Impulse Tracker");
|
||||
ImGui::SetTooltip(_("like Impulse Tracker"));
|
||||
}
|
||||
ImGui::Unindent();
|
||||
|
||||
if (e->song.linearPitch==2) {
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(120.0f*dpiScale);
|
||||
if (ImGui::InputScalar("Pitch slide speed multiplier",ImGuiDataType_U8,&e->song.pitchSlideSpeed,&_ONE,&_ONE)) {
|
||||
if (ImGui::InputScalar(_("Pitch slide speed multiplier"),ImGuiDataType_U8,&e->song.pitchSlideSpeed,&_ONE,&_ONE)) {
|
||||
if (e->song.pitchSlideSpeed<1) e->song.pitchSlideSpeed=1;
|
||||
if (e->song.pitchSlideSpeed>64) e->song.pitchSlideSpeed=64;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Text("Loop modality:");
|
||||
ImGui::Text(_("Loop modality:"));
|
||||
ImGui::Indent();
|
||||
if (ImGui::RadioButton("Reset channels",e->song.loopModality==0)) {
|
||||
if (ImGui::RadioButton(_("Reset channels"),e->song.loopModality==0)) {
|
||||
e->song.loopModality=0;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("select to reset channels on loop. may trigger a voltage click on every loop!");
|
||||
ImGui::SetTooltip(_("select to reset channels on loop. may trigger a voltage click on every loop!"));
|
||||
}
|
||||
if (ImGui::RadioButton("Soft reset channels",e->song.loopModality==1)) {
|
||||
if (ImGui::RadioButton(_("Soft reset channels"),e->song.loopModality==1)) {
|
||||
e->song.loopModality=1;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("select to turn channels off on loop.");
|
||||
ImGui::SetTooltip(_("select to turn channels off on loop."));
|
||||
}
|
||||
if (ImGui::RadioButton("Do nothing",e->song.loopModality==2)) {
|
||||
if (ImGui::RadioButton(_("Do nothing"),e->song.loopModality==2)) {
|
||||
e->song.loopModality=2;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("select to not reset channels on loop.");
|
||||
ImGui::SetTooltip(_("select to not reset channels on loop."));
|
||||
}
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::Text("Cut/delay effect policy:");
|
||||
ImGui::Text(_("Cut/delay effect policy:"));
|
||||
ImGui::Indent();
|
||||
if (ImGui::RadioButton("Strict",e->song.delayBehavior==0)) {
|
||||
if (ImGui::RadioButton(_("Strict"),e->song.delayBehavior==0)) {
|
||||
e->song.delayBehavior=0;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("only when time is less than speed (like DefleMask/ProTracker)");
|
||||
ImGui::SetTooltip(_("only when time is less than speed (like DefleMask/ProTracker)"));
|
||||
}
|
||||
if (ImGui::RadioButton("Strict (old)",e->song.delayBehavior==1)) {
|
||||
if (ImGui::RadioButton(_("Strict (old)"),e->song.delayBehavior==1)) {
|
||||
e->song.delayBehavior=1;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("only when time is less than or equal to speed (original buggy behavior)");
|
||||
ImGui::SetTooltip(_("only when time is less than or equal to speed (original buggy behavior)"));
|
||||
}
|
||||
if (ImGui::RadioButton("Lax",e->song.delayBehavior==2)) {
|
||||
if (ImGui::RadioButton(_("Lax"),e->song.delayBehavior==2)) {
|
||||
e->song.delayBehavior=2;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("no checks");
|
||||
ImGui::SetTooltip(_("no checks"));
|
||||
}
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::Text("Simultaneous jump (0B+0D) treatment:");
|
||||
ImGui::Text(_("Simultaneous jump (0B+0D) treatment:"));
|
||||
ImGui::Indent();
|
||||
if (ImGui::RadioButton("Normal",e->song.jumpTreatment==0)) {
|
||||
if (ImGui::RadioButton(_("Normal"),e->song.jumpTreatment==0)) {
|
||||
e->song.jumpTreatment=0;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("accept 0B+0D to jump to a specific row of an order");
|
||||
ImGui::SetTooltip(_("accept 0B+0D to jump to a specific row of an order"));
|
||||
}
|
||||
if (ImGui::RadioButton("Old Furnace",e->song.jumpTreatment==1)) {
|
||||
if (ImGui::RadioButton(_("Old Furnace"),e->song.jumpTreatment==1)) {
|
||||
e->song.jumpTreatment=1;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("only accept the first jump effect");
|
||||
ImGui::SetTooltip(_("only accept the first jump effect"));
|
||||
}
|
||||
if (ImGui::RadioButton("DefleMask",e->song.jumpTreatment==2)) {
|
||||
if (ImGui::RadioButton(_("DefleMask"),e->song.jumpTreatment==2)) {
|
||||
e->song.jumpTreatment=2;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("only accept 0Dxx");
|
||||
ImGui::SetTooltip(_("only accept 0Dxx"));
|
||||
}
|
||||
ImGui::Unindent();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Other")) {
|
||||
ImGui::Checkbox("Auto-insert one tick gap between notes",&e->song.oneTickCut);
|
||||
if (ImGui::BeginTabItem(_("Other"))) {
|
||||
ImGui::Checkbox(_("Auto-insert one tick gap between notes"),&e->song.oneTickCut);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("when enabled, a one-tick note cut will be inserted between non-legato/non-portamento notes.\nthis simulates the behavior of some Amiga/SNES music engines.\n\nineffective on C64.");
|
||||
ImGui::SetTooltip(_("when enabled, a one-tick note cut will be inserted between non-legato/non-portamento notes.\nthis simulates the behavior of some Amiga/SNES music engines.\n\nineffective on C64."));
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
InvCheckbox("Don't reset slides after note off",&e->song.noteOffResetsSlides);
|
||||
InvCheckbox(_("Don't reset slides after note off"),&e->song.noteOffResetsSlides);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("when enabled, note off will not reset the channel's slide effect.");
|
||||
ImGui::SetTooltip(_("when enabled, note off will not reset the channel's slide effect."));
|
||||
}
|
||||
InvCheckbox("Don't reset portamento after reaching target",&e->song.targetResetsSlides);
|
||||
InvCheckbox(_("Don't reset portamento after reaching target"),&e->song.targetResetsSlides);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("when enabled, the slide effect will not be disabled after it reaches its target.");
|
||||
ImGui::SetTooltip(_("when enabled, the slide effect will not be disabled after it reaches its target."));
|
||||
}
|
||||
ImGui::Checkbox("Continuous vibrato",&e->song.continuousVibrato);
|
||||
ImGui::Checkbox(_("Continuous vibrato"),&e->song.continuousVibrato);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("when enabled, vibrato phase/position will not be reset on a new note.");
|
||||
ImGui::SetTooltip(_("when enabled, vibrato phase/position will not be reset on a new note."));
|
||||
}
|
||||
InvCheckbox("Pitch macro is not linear",&e->song.pitchMacroIsLinear);
|
||||
InvCheckbox(_("Pitch macro is not linear"),&e->song.pitchMacroIsLinear);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("when enabled, the pitch macro of an instrument is in frequency/period space.");
|
||||
ImGui::SetTooltip(_("when enabled, the pitch macro of an instrument is in frequency/period space."));
|
||||
}
|
||||
ImGui::Checkbox("Reset arpeggio effect position on new note",&e->song.resetArpPhaseOnNewNote);
|
||||
ImGui::Checkbox(_("Reset arpeggio effect position on new note"),&e->song.resetArpPhaseOnNewNote);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("when enabled, arpeggio effect (00xy) position is reset on a new note.");
|
||||
ImGui::SetTooltip(_("when enabled, arpeggio effect (00xy) position is reset on a new note."));
|
||||
}
|
||||
ImGui::Checkbox("Volume scaling rounds up",&e->song.ceilVolumeScaling);
|
||||
ImGui::Checkbox(_("Volume scaling rounds up"),&e->song.ceilVolumeScaling);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("when enabled, volume macros round up when applied\nthis prevents volume scaling from causing vol=0, which is silent on some chips\n\nineffective on logarithmic channels");
|
||||
ImGui::SetTooltip(_("when enabled, volume macros round up when applied\nthis prevents volume scaling from causing vol=0, which is silent on some chips\n\nineffective on logarithmic channels"));
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,18 +109,18 @@ void FurnaceGUI::drawCSPlayer() {
|
|||
nextWindow=GUI_WINDOW_NOTHING;
|
||||
}
|
||||
if (!csPlayerOpen) return;
|
||||
if (ImGui::Begin("Command Stream Player",&csPlayerOpen,globalWinFlags)) {
|
||||
if (ImGui::Button("Load")) {
|
||||
if (ImGui::Begin("Command Stream Player",&csPlayerOpen,globalWinFlags,_("Command Stream Player"))) {
|
||||
if (ImGui::Button(_("Load"))) {
|
||||
openFileDialog(GUI_FILE_CMDSTREAM_OPEN);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Kill")) {
|
||||
if (ImGui::Button(_("Kill"))) {
|
||||
if (!e->killStream()) {
|
||||
showError("Kikai wa mou shindeiru!");
|
||||
showError(_("Kikai wa mou shindeiru!"));
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Burn Current Song")) {
|
||||
if (ImGui::Button(_("Burn Current Song"))) {
|
||||
SafeWriter* w=e->saveCommand();
|
||||
if (w!=NULL) {
|
||||
if (!e->playStream(w->getFinalBuf(),w->size())) {
|
||||
|
|
@ -138,34 +138,34 @@ void FurnaceGUI::drawCSPlayer() {
|
|||
if (cs) {
|
||||
if (ImGui::BeginTabBar("CSOptions")) {
|
||||
int chans=e->getTotalChannelCount();
|
||||
if (ImGui::BeginTabItem("Status")) {
|
||||
if (ImGui::BeginTabItem(_("Status"))) {
|
||||
if (ImGui::BeginTable("CSStat",12,ImGuiTableFlags_SizingFixedSame|ImGuiTableFlags_ScrollX|ImGuiTableFlags_Borders)) {
|
||||
ImGui::TableSetupScrollFreeze(1,1);
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("channel");
|
||||
ImGui::Text(_("channel"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("start");
|
||||
ImGui::Text(_("start"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("PC");
|
||||
ImGui::Text(_("PC"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("wait");
|
||||
ImGui::Text(_("wait"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("SP");
|
||||
ImGui::Text(_("SP"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("note");
|
||||
ImGui::Text(_("note"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("pitch");
|
||||
ImGui::Text(_("pitch"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("vol");
|
||||
ImGui::Text(_("vol"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("vols");
|
||||
ImGui::Text(_("vols"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("vib");
|
||||
ImGui::Text(_("vib"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("porta");
|
||||
ImGui::Text(_("porta"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("arp");
|
||||
ImGui::Text(_("arp"));
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
DivCSChannelState* state=cs->getChanState(i);
|
||||
|
|
@ -200,7 +200,7 @@ void FurnaceGUI::drawCSPlayer() {
|
|||
}
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Trace")) {
|
||||
if (ImGui::BeginTabItem(_("Trace"))) {
|
||||
ImGui::PushFont(patFont);
|
||||
if (ImGui::BeginTable("CSTrace",chans,ImGuiTableFlags_SizingFixedSame|ImGuiTableFlags_Borders|ImGuiTableFlags_ScrollX)) {
|
||||
char tempID[32];
|
||||
|
|
@ -241,10 +241,10 @@ void FurnaceGUI::drawCSPlayer() {
|
|||
ImGui::PopFont();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Disassemble")) {
|
||||
if (ImGui::BeginTabItem(_("Disassemble"))) {
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Hex")) {
|
||||
if (ImGui::BeginTabItem(_("Hex"))) {
|
||||
ImGui::PushFont(patFont);
|
||||
if (ImGui::BeginTable("CSHexPos",chans,ImGuiTableFlags_SizingStretchSame)) {
|
||||
ImGui::TableNextRow();
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ void FurnaceGUI::finishSelection() {
|
|||
selEnd.xFine=2+e->curPat[selEnd.xCoarse].effectCols*2;
|
||||
}
|
||||
|
||||
logV("finish selection: %d.%d,%d - %d.%d,%d",selStart.xCoarse,selStart.xFine,selStart.y,selEnd.xCoarse,selEnd.xFine,selEnd.y);
|
||||
logV(_("finish selection: %d.%d,%d - %d.%d,%d"),selStart.xCoarse,selStart.xFine,selStart.y,selEnd.xCoarse,selEnd.xFine,selEnd.y);
|
||||
|
||||
e->setMidiBaseChan(cursor.xCoarse);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,10 +73,10 @@ const char* sampleNote[12]={
|
|||
void FurnaceGUI::insListItem(int i, int dir, int asset) {
|
||||
ImGui::PushID(i);
|
||||
String name=(settings.insIconsStyle==0)?"":ICON_FA_CIRCLE_O;
|
||||
const char* insType="Bug!";
|
||||
const char* insType=_("Bug!");
|
||||
if (i>=0 && i<e->song.insLen) {
|
||||
DivInstrument* ins=e->song.ins[i];
|
||||
insType=(ins->type>=DIV_INS_MAX)?"Unknown":insTypes[ins->type][0];
|
||||
insType=(ins->type>=DIV_INS_MAX)?_("Unknown"):_(insTypes[ins->type][0]);
|
||||
const char** insIcon=NULL;
|
||||
|
||||
if (ins->type>=DIV_INS_MAX) {
|
||||
|
|
@ -113,7 +113,7 @@ void FurnaceGUI::insListItem(int i, int dir, int asset) {
|
|||
if (settings.insFocusesPattern && patternOpen)
|
||||
nextWindow=GUI_WINDOW_PATTERN;
|
||||
}
|
||||
if (wantScrollList && curIns==i) ImGui::SetScrollHereY();
|
||||
if (wantScrollListIns && curIns==i) ImGui::SetScrollHereY();
|
||||
if (ImGui::IsItemHovered() && i>=0 && !mobileUI) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_TEXT]);
|
||||
ImGui::SetTooltip("%s",insType);
|
||||
|
|
@ -133,19 +133,19 @@ void FurnaceGUI::insListItem(int i, int dir, int asset) {
|
|||
curIns=i;
|
||||
updateFMPreview=true;
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_TEXT]);
|
||||
if (ImGui::MenuItem("duplicate")) {
|
||||
if (ImGui::MenuItem(_("duplicate"))) {
|
||||
doAction(GUI_ACTION_INS_LIST_DUPLICATE);
|
||||
}
|
||||
if (ImGui::MenuItem("replace...")) {
|
||||
if (ImGui::MenuItem(_("replace..."))) {
|
||||
doAction((curIns>=0 && curIns<(int)e->song.ins.size())?GUI_ACTION_INS_LIST_OPEN_REPLACE:GUI_ACTION_INS_LIST_OPEN);
|
||||
}
|
||||
if (ImGui::MenuItem("save")) {
|
||||
if (ImGui::MenuItem(_("save"))) {
|
||||
doAction(GUI_ACTION_INS_LIST_SAVE);
|
||||
}
|
||||
if (ImGui::MenuItem("save (.dmp)")) {
|
||||
if (ImGui::MenuItem(_("save (.dmp)"))) {
|
||||
doAction(GUI_ACTION_INS_LIST_SAVE_DMP);
|
||||
}
|
||||
if (ImGui::MenuItem("delete")) {
|
||||
if (ImGui::MenuItem(_("delete"))) {
|
||||
doAction(GUI_ACTION_INS_LIST_DELETE);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
|
|
@ -156,14 +156,14 @@ void FurnaceGUI::insListItem(int i, int dir, int asset) {
|
|||
if (i<(int)e->song.ins.size()) {
|
||||
DivInstrument* ins=e->song.ins[i];
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%.2X: %s",i,ins->name.c_str());
|
||||
ImGui::TextNoHashHide("%.2X: %s",i,ins->name.c_str());
|
||||
} else {
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%.2X: <INVALID>",i);
|
||||
ImGui::TextNoHashHide("%.2X: <INVALID>",i);
|
||||
}
|
||||
} else {
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("- None -");
|
||||
ImGui::TextNoHashHide("- None -");
|
||||
}
|
||||
ImGui::PopID();
|
||||
ImGui::PopStyleColor();
|
||||
|
|
@ -183,7 +183,7 @@ void FurnaceGUI::waveListItem(int i, float* wavePreview, int dir, int asset) {
|
|||
}
|
||||
ImGui::PopStyleVar();
|
||||
curPos.x+=ImGui::CalcTextSize("2222").x;
|
||||
if (wantScrollList && curWave==i) ImGui::SetScrollHereY();
|
||||
if (wantScrollListWave && curWave==i) ImGui::SetScrollHereY();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
|
||||
waveEditOpen=true;
|
||||
|
|
@ -219,7 +219,7 @@ void FurnaceGUI::sampleListItem(int i, int dir, int asset) {
|
|||
if (memWarning) break;
|
||||
}
|
||||
if (memWarning) ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_SAMPLE_CHIP_WARNING]);
|
||||
if (ImGui::Selectable(fmt::sprintf("%d: %s##_SAM%d",i,sample->name,i).c_str(),curSample==i)) {
|
||||
if (ImGui::Selectable(fmt::sprintf("%d:##_SAM%d",i,i).c_str(),curSample==i)) {
|
||||
curSample=i;
|
||||
samplePos=0;
|
||||
updateSampleTex=true;
|
||||
|
|
@ -235,12 +235,14 @@ void FurnaceGUI::sampleListItem(int i, int dir, int asset) {
|
|||
DRAG_SOURCE(dir,asset,"FUR_SDIR");
|
||||
DRAG_TARGET(dir,asset,e->song.sampleDir,"FUR_SDIR");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::TextNoHashHide("%s",sample->name.c_str());
|
||||
if (memWarning) {
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(ICON_FA_EXCLAMATION_TRIANGLE);
|
||||
if (ImGui::IsItemHovered() && !mobileUI) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_TEXT]);
|
||||
ImGui::SetTooltip("out of memory for this sample!");
|
||||
ImGui::SetTooltip(_("out of memory for this sample!"));
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
|
|
@ -251,28 +253,28 @@ void FurnaceGUI::sampleListItem(int i, int dir, int asset) {
|
|||
updateSampleTex=true;
|
||||
lastAssetType=2;
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_TEXT]);
|
||||
if (ImGui::MenuItem("make instrument")) {
|
||||
if (ImGui::MenuItem(_("make instrument"))) {
|
||||
doAction(GUI_ACTION_SAMPLE_MAKE_INS);
|
||||
}
|
||||
if (ImGui::MenuItem("make me a drum kit")) {
|
||||
if (ImGui::MenuItem(_("make me a drum kit"))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_MAKE_MAP);
|
||||
}
|
||||
if (ImGui::MenuItem("duplicate")) {
|
||||
if (ImGui::MenuItem(_("duplicate"))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_DUPLICATE);
|
||||
}
|
||||
if (ImGui::MenuItem("replace...")) {
|
||||
if (ImGui::MenuItem(_("replace..."))) {
|
||||
doAction((curSample>=0 && curSample<(int)e->song.sample.size())?GUI_ACTION_SAMPLE_LIST_OPEN_REPLACE:GUI_ACTION_SAMPLE_LIST_OPEN);
|
||||
}
|
||||
if (ImGui::MenuItem("save")) {
|
||||
if (ImGui::MenuItem(_("save"))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_SAVE);
|
||||
}
|
||||
if (ImGui::MenuItem("delete")) {
|
||||
if (ImGui::MenuItem(_("delete"))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_DELETE);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
if (wantScrollList && curSample==i) ImGui::SetScrollHereY();
|
||||
if (wantScrollListSample && curSample==i) ImGui::SetScrollHereY();
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
|
|
@ -287,7 +289,7 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
if (asChild) {
|
||||
began=ImGui::BeginChild("Instruments");
|
||||
} else {
|
||||
began=ImGui::Begin("Instruments",&insListOpen,globalWinFlags);
|
||||
began=ImGui::Begin("Instruments",&insListOpen,globalWinFlags,_("Instruments"));
|
||||
}
|
||||
if (began) {
|
||||
if (settings.unifiedDataView) settings.horizontalDataView=0;
|
||||
|
|
@ -309,7 +311,7 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
}
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Add");
|
||||
ImGui::SetTooltip(_("Add"));
|
||||
}
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
|
||||
makeInsTypeList=e->getPossibleInsTypes();
|
||||
|
|
@ -335,7 +337,7 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
}
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Duplicate");
|
||||
ImGui::SetTooltip(_("Duplicate"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_FOLDER_OPEN "##InsLoad")) {
|
||||
|
|
@ -356,47 +358,47 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
}
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Open");
|
||||
ImGui::SetTooltip(_("Open"));
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("InsOpenOpt")) {
|
||||
if (settings.unifiedDataView) {
|
||||
if (ImGui::MenuItem("replace instrument...")) {
|
||||
if (ImGui::MenuItem(_("replace instrument..."))) {
|
||||
doAction((curIns>=0 && curIns<(int)e->song.ins.size())?GUI_ACTION_INS_LIST_OPEN_REPLACE:GUI_ACTION_INS_LIST_OPEN);
|
||||
}
|
||||
if (ImGui::MenuItem("load instrument from TX81Z")) {
|
||||
if (ImGui::MenuItem(_("load instrument from TX81Z"))) {
|
||||
doAction(GUI_ACTION_TX81Z_REQUEST);
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("replace wavetable...")) {
|
||||
if (ImGui::MenuItem(_("replace wavetable..."))) {
|
||||
doAction((curWave>=0 && curWave<(int)e->song.wave.size())?GUI_ACTION_WAVE_LIST_OPEN_REPLACE:GUI_ACTION_WAVE_LIST_OPEN);
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("replace sample...")) {
|
||||
if (ImGui::MenuItem(_("replace sample..."))) {
|
||||
doAction((curSample>=0 && curSample<(int)e->song.sample.size())?GUI_ACTION_SAMPLE_LIST_OPEN_REPLACE:GUI_ACTION_SAMPLE_LIST_OPEN);
|
||||
}
|
||||
if (ImGui::MenuItem("import raw sample...")) {
|
||||
if (ImGui::MenuItem(_("import raw sample..."))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_OPEN_RAW);
|
||||
}
|
||||
if (ImGui::MenuItem("import raw sample (replace)...")) {
|
||||
if (ImGui::MenuItem(_("import raw sample (replace)..."))) {
|
||||
doAction((curSample>=0 && curSample<(int)e->song.sample.size())?GUI_ACTION_SAMPLE_LIST_OPEN_REPLACE_RAW:GUI_ACTION_SAMPLE_LIST_OPEN_RAW);
|
||||
}
|
||||
} else {
|
||||
if (ImGui::MenuItem("replace...")) {
|
||||
if (ImGui::MenuItem(_("replace..."))) {
|
||||
doAction((curIns>=0 && curIns<(int)e->song.ins.size())?GUI_ACTION_INS_LIST_OPEN_REPLACE:GUI_ACTION_INS_LIST_OPEN);
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("load from TX81Z")) {
|
||||
if (ImGui::MenuItem(_("load from TX81Z"))) {
|
||||
doAction(GUI_ACTION_TX81Z_REQUEST);
|
||||
}
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Open (insert; right-click to replace)");
|
||||
ImGui::SetTooltip(_("Open (insert; right-click to replace)"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_FLOPPY_O "##InsSave")) {
|
||||
|
|
@ -417,32 +419,48 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
}
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Save");
|
||||
ImGui::SetTooltip(_("Save"));
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("InsSaveFormats",ImGuiMouseButton_Right)) {
|
||||
if (settings.unifiedDataView) {
|
||||
if (ImGui::MenuItem("save instrument as .dmp...")) {
|
||||
if (ImGui::MenuItem(_("save instrument as .dmp..."))) {
|
||||
doAction(GUI_ACTION_INS_LIST_SAVE_DMP);
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("save wavetable as .dmw...")) {
|
||||
if (ImGui::MenuItem(_("save wavetable as .dmw..."))) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_SAVE_DMW);
|
||||
}
|
||||
if (ImGui::MenuItem("save raw wavetable...")) {
|
||||
if (ImGui::MenuItem(_("save raw wavetable..."))) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_SAVE_RAW);
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("save raw sample...")) {
|
||||
if (ImGui::MenuItem(_("save raw sample..."))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_SAVE_RAW);
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem(_("save all instruments..."))) {
|
||||
doAction(GUI_ACTION_INS_LIST_SAVE_ALL);
|
||||
}
|
||||
if (ImGui::MenuItem(_("save all wavetables..."))) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_SAVE_ALL);
|
||||
}
|
||||
if (ImGui::MenuItem(_("save all samples..."))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_SAVE_ALL);
|
||||
}
|
||||
} else {
|
||||
if (ImGui::MenuItem("save as .dmp...")) {
|
||||
if (ImGui::MenuItem(_("save as .dmp..."))) {
|
||||
doAction(GUI_ACTION_INS_LIST_SAVE_DMP);
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem(_("save all..."))) {
|
||||
doAction(GUI_ACTION_INS_LIST_SAVE_ALL);
|
||||
}
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
|
@ -453,7 +471,7 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
}
|
||||
popToggleColors();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Toggle folders/standard view");
|
||||
ImGui::SetTooltip(_("Toggle folders/standard view"));
|
||||
}
|
||||
if (!insListDir) {
|
||||
ImGui::SameLine();
|
||||
|
|
@ -475,7 +493,7 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
}
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Move up");
|
||||
ImGui::SetTooltip(_("Move up"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_ARROW_DOWN "##InsDown")) {
|
||||
|
|
@ -496,7 +514,7 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
}
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Move down");
|
||||
ImGui::SetTooltip(_("Move down"));
|
||||
}
|
||||
} else {
|
||||
ImGui::SameLine();
|
||||
|
|
@ -507,7 +525,7 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
ImGui::InputText("##FolderName",&folderString);
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginDisabled(folderString.empty());
|
||||
if (ImGui::Button("Create")) {
|
||||
if (ImGui::Button(_("Create"))) {
|
||||
if (settings.unifiedDataView) {
|
||||
switch (lastAssetType) {
|
||||
case 0:
|
||||
|
|
@ -537,7 +555,7 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
ImGui::EndPopup();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("New folder");
|
||||
ImGui::SetTooltip(_("New folder"));
|
||||
}
|
||||
}
|
||||
if (lastAssetType==2) {
|
||||
|
|
@ -546,7 +564,7 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
doAction(GUI_ACTION_SAMPLE_LIST_PREVIEW);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Preview (right click to stop)");
|
||||
ImGui::SetTooltip(_("Preview (right click to stop)"));
|
||||
}
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_STOP_PREVIEW);
|
||||
|
|
@ -573,7 +591,7 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
}
|
||||
popDestColor();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Delete");
|
||||
ImGui::SetTooltip(_("Delete"));
|
||||
}
|
||||
ImGui::Separator();
|
||||
int availableRows=ImGui::GetContentRegionAvail().y/ImGui::GetFrameHeight();
|
||||
|
|
@ -590,7 +608,7 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
lastAssetType=0;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("Instruments");
|
||||
ImGui::Text(_("Instruments"));
|
||||
ImGui::Indent();
|
||||
}
|
||||
|
||||
|
|
@ -605,16 +623,16 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
int dirIndex=0;
|
||||
int dirToDelete=-1;
|
||||
for (DivAssetDir& i: e->song.insDir) {
|
||||
String nodeName=fmt::sprintf("%s %s##_ADI%d",i.name.empty()?ICON_FA_FOLDER_O:ICON_FA_FOLDER,i.name.empty()?"<uncategorized>":i.name,i.name.empty()?-1:dirIndex);
|
||||
String nodeName=fmt::sprintf("%s %s##_ADI%d",i.name.empty()?ICON_FA_FOLDER_O:ICON_FA_FOLDER,i.name.empty()?_("<uncategorized>"):i.name,i.name.empty()?-1:dirIndex);
|
||||
String popupID=fmt::sprintf("DirRightMenu%d",dirIndex);
|
||||
bool treeNode=ImGui::TreeNodeEx(nodeName.c_str(),ImGuiTreeNodeFlags_SpanAvailWidth|(i.name.empty()?ImGuiTreeNodeFlags_DefaultOpen:0));
|
||||
DRAG_SOURCE(dirIndex,-1,"FUR_INSDIR");
|
||||
DRAG_TARGET(dirIndex,-1,e->song.insDir,"FUR_INSDIR");
|
||||
if (ImGui::BeginPopupContextItem(popupID.c_str())) {
|
||||
if (ImGui::MenuItem("rename...")) {
|
||||
if (ImGui::MenuItem(_("rename..."))) {
|
||||
editStr(&i.name);
|
||||
}
|
||||
if (ImGui::MenuItem("delete")) {
|
||||
if (ImGui::MenuItem(_("delete"))) {
|
||||
dirToDelete=dirIndex;
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
|
|
@ -660,7 +678,7 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
lastAssetType=1;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("Wavetables");
|
||||
ImGui::Text(_("Wavetables"));
|
||||
ImGui::Indent();
|
||||
actualWaveList();
|
||||
ImGui::Unindent();
|
||||
|
|
@ -671,7 +689,7 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
lastAssetType=2;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("Samples");
|
||||
ImGui::Text(_("Samples"));
|
||||
ImGui::Indent();
|
||||
actualSampleList();
|
||||
ImGui::Unindent();
|
||||
|
|
@ -704,31 +722,31 @@ void FurnaceGUI::drawWaveList(bool asChild) {
|
|||
if (asChild) {
|
||||
began=ImGui::BeginChild("Wavetables");
|
||||
} else {
|
||||
began=ImGui::Begin("Wavetables",&waveListOpen,globalWinFlags);
|
||||
began=ImGui::Begin("Wavetables",&waveListOpen,globalWinFlags,_("Wavetables"));
|
||||
}
|
||||
if (began) {
|
||||
if (ImGui::Button(ICON_FA_PLUS "##WaveAdd")) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_ADD);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Add");
|
||||
ImGui::SetTooltip(_("Add"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_FILES_O "##WaveClone")) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_DUPLICATE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Duplicate");
|
||||
ImGui::SetTooltip(_("Duplicate"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_FOLDER_OPEN "##WaveLoad")) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_OPEN);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Open");
|
||||
ImGui::SetTooltip(_("Open"));
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("WaveOpenOpt")) {
|
||||
if (ImGui::MenuItem("replace...")) {
|
||||
if (ImGui::MenuItem(_("replace..."))) {
|
||||
doAction((curWave>=0 && curWave<(int)e->song.wave.size())?GUI_ACTION_WAVE_LIST_OPEN_REPLACE:GUI_ACTION_WAVE_LIST_OPEN);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
|
|
@ -738,16 +756,19 @@ void FurnaceGUI::drawWaveList(bool asChild) {
|
|||
doAction(GUI_ACTION_WAVE_LIST_SAVE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Save");
|
||||
ImGui::SetTooltip(_("Save"));
|
||||
}
|
||||
if (!settings.unifiedDataView) {
|
||||
if (ImGui::BeginPopupContextItem("WaveSaveFormats",ImGuiMouseButton_Right)) {
|
||||
if (ImGui::MenuItem("save as .dmw...")) {
|
||||
if (ImGui::MenuItem(_("save as .dmw..."))) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_SAVE_DMW);
|
||||
}
|
||||
if (ImGui::MenuItem("save raw...")) {
|
||||
if (ImGui::MenuItem(_("save raw..."))) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_SAVE_RAW);
|
||||
}
|
||||
if (ImGui::MenuItem(_("save all..."))) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_SAVE_ALL);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
|
@ -758,7 +779,7 @@ void FurnaceGUI::drawWaveList(bool asChild) {
|
|||
}
|
||||
popToggleColors();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Toggle folders/standard view");
|
||||
ImGui::SetTooltip(_("Toggle folders/standard view"));
|
||||
}
|
||||
if (!waveListDir) {
|
||||
ImGui::SameLine();
|
||||
|
|
@ -766,14 +787,14 @@ void FurnaceGUI::drawWaveList(bool asChild) {
|
|||
doAction(GUI_ACTION_WAVE_LIST_MOVE_UP);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Move up");
|
||||
ImGui::SetTooltip(_("Move up"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_ARROW_DOWN "##WaveDown")) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_MOVE_DOWN);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Move down");
|
||||
ImGui::SetTooltip(_("Move down"));
|
||||
}
|
||||
} else {
|
||||
ImGui::SameLine();
|
||||
|
|
@ -784,7 +805,7 @@ void FurnaceGUI::drawWaveList(bool asChild) {
|
|||
ImGui::InputText("##FolderName",&folderString);
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginDisabled(folderString.empty());
|
||||
if (ImGui::Button("Create")) {
|
||||
if (ImGui::Button(_("Create"))) {
|
||||
e->lockEngine([this]() {
|
||||
e->song.waveDir.push_back(DivAssetDir(folderString));
|
||||
});
|
||||
|
|
@ -794,7 +815,7 @@ void FurnaceGUI::drawWaveList(bool asChild) {
|
|||
ImGui::EndPopup();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("New folder");
|
||||
ImGui::SetTooltip(_("New folder"));
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
|
@ -804,7 +825,7 @@ void FurnaceGUI::drawWaveList(bool asChild) {
|
|||
}
|
||||
popDestColor();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Delete");
|
||||
ImGui::SetTooltip(_("Delete"));
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginTable("WaveListScroll",1,ImGuiTableFlags_ScrollY)) {
|
||||
|
|
@ -836,42 +857,42 @@ void FurnaceGUI::drawSampleList(bool asChild) {
|
|||
if (asChild) {
|
||||
began=ImGui::BeginChild("Samples");
|
||||
} else {
|
||||
began=ImGui::Begin("Samples",&sampleListOpen,globalWinFlags);
|
||||
began=ImGui::Begin("Samples",&sampleListOpen,globalWinFlags,_("Samples"));
|
||||
}
|
||||
if (began) {
|
||||
if (ImGui::Button(ICON_FA_FILE "##SampleAdd")) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_ADD);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Add");
|
||||
ImGui::SetTooltip(_("Add"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_FILES_O "##SampleClone")) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_DUPLICATE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Duplicate");
|
||||
ImGui::SetTooltip(_("Duplicate"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_FOLDER_OPEN "##SampleLoad")) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_OPEN);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Open");
|
||||
ImGui::SetTooltip(_("Open"));
|
||||
}
|
||||
if (mobileUI && ImGui::IsItemActive() && CHECK_LONG_HOLD) {
|
||||
ImGui::OpenPopup("SampleOpenOpt");
|
||||
NOTIFY_LONG_HOLD;
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("SampleOpenOpt")) {
|
||||
if (ImGui::MenuItem("replace...")) {
|
||||
if (ImGui::MenuItem(_("replace..."))) {
|
||||
doAction((curSample>=0 && curSample<(int)e->song.sample.size())?GUI_ACTION_SAMPLE_LIST_OPEN_REPLACE:GUI_ACTION_SAMPLE_LIST_OPEN);
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("import raw...")) {
|
||||
if (ImGui::MenuItem(_("import raw..."))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_OPEN_RAW);
|
||||
}
|
||||
if (ImGui::MenuItem("import raw (replace)...")) {
|
||||
if (ImGui::MenuItem(_("import raw (replace)..."))) {
|
||||
doAction((curSample>=0 && curSample<(int)e->song.sample.size())?GUI_ACTION_SAMPLE_LIST_OPEN_REPLACE_RAW:GUI_ACTION_SAMPLE_LIST_OPEN_RAW);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
|
|
@ -881,16 +902,19 @@ void FurnaceGUI::drawSampleList(bool asChild) {
|
|||
doAction(GUI_ACTION_SAMPLE_LIST_SAVE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Save");
|
||||
ImGui::SetTooltip(_("Save"));
|
||||
}
|
||||
if (mobileUI && ImGui::IsItemActive() && CHECK_LONG_HOLD) {
|
||||
ImGui::OpenPopup("SampleSaveOpt");
|
||||
NOTIFY_LONG_HOLD;
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("SampleSaveOpt")) {
|
||||
if (ImGui::MenuItem("save raw...")) {
|
||||
if (ImGui::MenuItem(_("save raw..."))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_SAVE_RAW);
|
||||
}
|
||||
if (ImGui::MenuItem(_("save all..."))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_SAVE_ALL);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
|
@ -900,7 +924,7 @@ void FurnaceGUI::drawSampleList(bool asChild) {
|
|||
}
|
||||
popToggleColors();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Toggle folders/standard view");
|
||||
ImGui::SetTooltip(_("Toggle folders/standard view"));
|
||||
}
|
||||
if (!sampleListDir) {
|
||||
ImGui::SameLine();
|
||||
|
|
@ -908,14 +932,14 @@ void FurnaceGUI::drawSampleList(bool asChild) {
|
|||
doAction(GUI_ACTION_SAMPLE_LIST_MOVE_UP);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Move up");
|
||||
ImGui::SetTooltip(_("Move up"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_ARROW_DOWN "##SampleDown")) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_MOVE_DOWN);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Move down");
|
||||
ImGui::SetTooltip(_("Move down"));
|
||||
}
|
||||
} else {
|
||||
ImGui::SameLine();
|
||||
|
|
@ -926,7 +950,7 @@ void FurnaceGUI::drawSampleList(bool asChild) {
|
|||
ImGui::InputText("##FolderName",&folderString);
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginDisabled(folderString.empty());
|
||||
if (ImGui::Button("Create")) {
|
||||
if (ImGui::Button(_("Create"))) {
|
||||
e->lockEngine([this]() {
|
||||
e->song.sampleDir.push_back(DivAssetDir(folderString));
|
||||
});
|
||||
|
|
@ -936,7 +960,7 @@ void FurnaceGUI::drawSampleList(bool asChild) {
|
|||
ImGui::EndPopup();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("New folder");
|
||||
ImGui::SetTooltip(_("New folder"));
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
|
@ -944,7 +968,7 @@ void FurnaceGUI::drawSampleList(bool asChild) {
|
|||
doAction(GUI_ACTION_SAMPLE_LIST_PREVIEW);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Preview (right click to stop)");
|
||||
ImGui::SetTooltip(_("Preview (right click to stop)"));
|
||||
}
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_STOP_PREVIEW);
|
||||
|
|
@ -956,7 +980,7 @@ void FurnaceGUI::drawSampleList(bool asChild) {
|
|||
}
|
||||
popDestColor();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Delete");
|
||||
ImGui::SetTooltip(_("Delete"));
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginTable("SampleListScroll",1,ImGuiTableFlags_ScrollY)) {
|
||||
|
|
@ -982,16 +1006,16 @@ void FurnaceGUI::actualWaveList() {
|
|||
int dirIndex=0;
|
||||
int dirToDelete=-1;
|
||||
for (DivAssetDir& i: e->song.waveDir) {
|
||||
String nodeName=fmt::sprintf("%s %s##_ADW%d",i.name.empty()?ICON_FA_FOLDER_O:ICON_FA_FOLDER,i.name.empty()?"<uncategorized>":i.name,i.name.empty()?-1:dirIndex);
|
||||
String nodeName=fmt::sprintf("%s %s##_ADW%d",i.name.empty()?ICON_FA_FOLDER_O:ICON_FA_FOLDER,i.name.empty()?_("<uncategorized>"):i.name,i.name.empty()?-1:dirIndex);
|
||||
String popupID=fmt::sprintf("DirRightMenu%d",dirIndex);
|
||||
bool treeNode=ImGui::TreeNodeEx(nodeName.c_str(),ImGuiTreeNodeFlags_SpanAvailWidth|(i.name.empty()?ImGuiTreeNodeFlags_DefaultOpen:0));
|
||||
DRAG_SOURCE(dirIndex,-1,"FUR_WAVEDIR");
|
||||
DRAG_TARGET(dirIndex,-1,e->song.waveDir,"FUR_WAVEDIR");
|
||||
if (ImGui::BeginPopupContextItem(popupID.c_str())) {
|
||||
if (ImGui::MenuItem("rename...")) {
|
||||
if (ImGui::MenuItem(_("rename..."))) {
|
||||
editStr(&i.name);
|
||||
}
|
||||
if (ImGui::MenuItem("delete")) {
|
||||
if (ImGui::MenuItem(_("delete"))) {
|
||||
dirToDelete=dirIndex;
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
|
|
@ -1028,16 +1052,16 @@ void FurnaceGUI::actualSampleList() {
|
|||
int dirIndex=0;
|
||||
int dirToDelete=-1;
|
||||
for (DivAssetDir& i: e->song.sampleDir) {
|
||||
String nodeName=fmt::sprintf("%s %s##_ADS%d",i.name.empty()?ICON_FA_FOLDER_O:ICON_FA_FOLDER,i.name.empty()?"<uncategorized>":i.name,i.name.empty()?-1:dirIndex);
|
||||
String nodeName=fmt::sprintf("%s %s##_ADS%d",i.name.empty()?ICON_FA_FOLDER_O:ICON_FA_FOLDER,i.name.empty()?_("<uncategorized>"):i.name,i.name.empty()?-1:dirIndex);
|
||||
String popupID=fmt::sprintf("DirRightMenu%d",dirIndex);
|
||||
bool treeNode=ImGui::TreeNodeEx(nodeName.c_str(),ImGuiTreeNodeFlags_SpanAvailWidth|(i.name.empty()?ImGuiTreeNodeFlags_DefaultOpen:0));
|
||||
DRAG_SOURCE(dirIndex,-1,"FUR_SDIR");
|
||||
DRAG_TARGET(dirIndex,-1,e->song.sampleDir,"FUR_SDIR");
|
||||
if (ImGui::BeginPopupContextItem(popupID.c_str())) {
|
||||
if (ImGui::MenuItem("rename...")) {
|
||||
if (ImGui::MenuItem(_("rename..."))) {
|
||||
editStr(&i.name);
|
||||
}
|
||||
if (ImGui::MenuItem("delete")) {
|
||||
if (ImGui::MenuItem(_("delete"))) {
|
||||
dirToDelete=dirIndex;
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
|
|
|
|||
|
|
@ -315,9 +315,7 @@ void putDispatchChip(void* data, int type) {
|
|||
ImGui::Text("> PCEngine");
|
||||
COMMON_CHIP_DEBUG;
|
||||
ImGui::Text("- lastPan: %d",ch->lastPan);
|
||||
ImGui::Text("- cycles: %d",ch->cycles);
|
||||
ImGui::Text("- curChan: %d",ch->curChan);
|
||||
ImGui::Text("- delay: %d",ch->delay);
|
||||
ImGui::Text("- sampleBank: %d",ch->sampleBank);
|
||||
ImGui::Text("- lfoMode: %d",ch->lfoMode);
|
||||
ImGui::Text("- lfoSpeed: %d",ch->lfoSpeed);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ static float oscDebugMin=-1.0;
|
|||
static float oscDebugMax=1.0;
|
||||
static float oscDebugPower=1.0;
|
||||
static int oscDebugRepeat=1;
|
||||
static int numApples=1;
|
||||
static int getGainChan=0;
|
||||
static int getGainVol=0;
|
||||
|
||||
static void _drawOsc(const ImDrawList* drawList, const ImDrawCmd* cmd) {
|
||||
if (cmd!=NULL) {
|
||||
|
|
@ -62,7 +65,7 @@ void FurnaceGUI::drawDebug() {
|
|||
}
|
||||
if (!debugOpen) return;
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(100.0f*dpiScale,100.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||
if (ImGui::Begin("Debug",&debugOpen,globalWinFlags|ImGuiWindowFlags_NoDocking)) {
|
||||
if (ImGui::Begin("Debug",&debugOpen,globalWinFlags|ImGuiWindowFlags_NoDocking,_("Debug"))) {
|
||||
ImGui::Text("NOTE: use with caution.");
|
||||
if (ImGui::TreeNode("Debug Controls")) {
|
||||
if (e->isHalted()) {
|
||||
|
|
@ -154,7 +157,7 @@ void FurnaceGUI::drawDebug() {
|
|||
ImGui::Text("- depth = %d",ch->vibratoDepth);
|
||||
ImGui::Text("- rate = %d",ch->vibratoRate);
|
||||
ImGui::Text("- pos = %d",ch->vibratoPos);
|
||||
ImGui::Text("- dir = %d",ch->vibratoDir);
|
||||
ImGui::Text("- shape = %d",ch->vibratoShape);
|
||||
ImGui::Text("- fine = %d",ch->vibratoFine);
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,(ch->tremoloDepth>0)?uiColors[GUI_COLOR_MACRO_VOLUME]:uiColors[GUI_COLOR_TEXT]);
|
||||
|
|
@ -610,6 +613,59 @@ void FurnaceGUI::drawDebug() {
|
|||
ImGui::Unindent();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Texture Test")) {
|
||||
ImGui::Text("Create and Destroy 128 Textures");
|
||||
if (ImGui::Button("No Write")) {
|
||||
for (int i=0; i<128; i++) {
|
||||
FurnaceGUITexture* t=rend->createTexture(false,2048,2048,true,bestTexFormat);
|
||||
if (t==NULL) {
|
||||
showError(fmt::sprintf("Failure! %d",i));
|
||||
break;
|
||||
}
|
||||
rend->destroyTexture(t);
|
||||
}
|
||||
}
|
||||
if (ImGui::Button("Write (update)")) {
|
||||
unsigned char* data=new unsigned char[2048*2048*4];
|
||||
for (int i=0; i<2048*2048*4; i++) {
|
||||
data[i]=rand();
|
||||
}
|
||||
for (int i=0; i<128; i++) {
|
||||
FurnaceGUITexture* t=rend->createTexture(false,2048,2048,true,bestTexFormat);
|
||||
if (t==NULL) {
|
||||
showError(fmt::sprintf("Failure! %d",i));
|
||||
break;
|
||||
}
|
||||
rend->updateTexture(t,data,2048*4);
|
||||
rend->destroyTexture(t);
|
||||
}
|
||||
delete[] data;
|
||||
}
|
||||
if (ImGui::Button("Write (lock)")) {
|
||||
unsigned char* data=NULL;
|
||||
int pitch=0;
|
||||
for (int i=0; i<128; i++) {
|
||||
FurnaceGUITexture* t=rend->createTexture(false,2048,2048,true,bestTexFormat);
|
||||
if (t==NULL) {
|
||||
showError(fmt::sprintf("Failure! %d",i));
|
||||
break;
|
||||
}
|
||||
if (rend->lockTexture(t,(void**)&data,&pitch)) {
|
||||
for (int i=0; i<2048*2048*4; i++) {
|
||||
data[i]=rand();
|
||||
}
|
||||
rend->unlockTexture(t);
|
||||
}
|
||||
rend->destroyTexture(t);
|
||||
}
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Locale Test")) {
|
||||
ImGui::TextUnformatted(_("This is a language test."));
|
||||
ImGui::TextUnformatted(_("This is another language test."));
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Osc Render Test")) {
|
||||
ImGui::InputInt("Length",&oscDebugLen);
|
||||
ImGui::InputInt("Height",&oscDebugHeight);
|
||||
|
|
@ -660,6 +716,20 @@ void FurnaceGUI::drawDebug() {
|
|||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
#ifdef HAVE_LOCALE
|
||||
if (ImGui::TreeNode("Plural Form Test")) {
|
||||
ImGui::InputInt("Number",&numApples);
|
||||
ImGui::Text(ngettext("%d apple","%d apples",numApples),numApples);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
#endif
|
||||
if (ImGui::TreeNode("Get Gain Test")) {
|
||||
float realVol=e->getGain(getGainChan,getGainVol);
|
||||
ImGui::InputInt("Chan",&getGainChan);
|
||||
ImGui::InputInt("Vol",&getGainVol);
|
||||
ImGui::Text("result: %.0f%%",realVol*100.0f);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("User Interface")) {
|
||||
if (ImGui::Button("Inspect")) {
|
||||
inspectorOpen=!inspectorOpen;
|
||||
|
|
|
|||
|
|
@ -35,21 +35,21 @@ void FurnaceGUI::doAction(int what) {
|
|||
switch (what) {
|
||||
case GUI_ACTION_NEW:
|
||||
if (modified) {
|
||||
showWarning("Unsaved changes! Save changes before creating a new song?",GUI_WARN_NEW);
|
||||
showWarning(_("Unsaved changes! Save changes before creating a new song?"),GUI_WARN_NEW);
|
||||
} else {
|
||||
displayNew=true;
|
||||
}
|
||||
break;
|
||||
case GUI_ACTION_OPEN:
|
||||
if (modified) {
|
||||
showWarning("Unsaved changes! Save changes before opening another file?",GUI_WARN_OPEN);
|
||||
showWarning(_("Unsaved changes! Save changes before opening another file?"),GUI_WARN_OPEN);
|
||||
} else {
|
||||
openFileDialog(GUI_FILE_OPEN);
|
||||
}
|
||||
break;
|
||||
case GUI_ACTION_OPEN_BACKUP:
|
||||
if (modified) {
|
||||
showWarning("Unsaved changes! Save changes before opening backup?",GUI_WARN_OPEN_BACKUP);
|
||||
showWarning(_("Unsaved changes! Save changes before opening backup?"),GUI_WARN_OPEN_BACKUP);
|
||||
} else {
|
||||
openFileDialog(GUI_FILE_OPEN_BACKUP);
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
openFileDialog(GUI_FILE_SAVE);
|
||||
} else {
|
||||
if (save(curFileName,e->song.isDMF?e->song.version:0)>0) {
|
||||
showError(fmt::sprintf("Error while saving file! (%s)",lastError));
|
||||
showError(fmt::sprintf(_("Error while saving file! (%s)"),lastError));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -143,7 +143,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
curIns=-1;
|
||||
}
|
||||
wavePreviewInit=true;
|
||||
wantScrollList=true;
|
||||
wantScrollListIns=true;
|
||||
updateFMPreview=true;
|
||||
break;
|
||||
case GUI_ACTION_INS_DOWN:
|
||||
|
|
@ -151,7 +151,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
curIns=((int)e->song.ins.size())-1;
|
||||
}
|
||||
wavePreviewInit=true;
|
||||
wantScrollList=true;
|
||||
wantScrollListIns=true;
|
||||
updateFMPreview=true;
|
||||
break;
|
||||
case GUI_ACTION_STEP_UP:
|
||||
|
|
@ -186,7 +186,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
msg.sysExLen=15;
|
||||
memcpy(msg.sysExData.get(),avRequest,15);
|
||||
if (!e->sendMidiMessage(msg)) {
|
||||
showError("Error while sending request (MIDI output not configured?)");
|
||||
showError(_("Error while sending request (MIDI output not configured?)"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -194,7 +194,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
e->syncReset();
|
||||
break;
|
||||
case GUI_ACTION_CLEAR:
|
||||
showWarning("Select an option: (cannot be undone!)",GUI_WARN_CLEAR);
|
||||
showWarning(_("Select an option: (cannot be undone!)"),GUI_WARN_CLEAR);
|
||||
break;
|
||||
case GUI_ACTION_COMMAND_PALETTE:
|
||||
displayPalette=true;
|
||||
|
|
@ -319,6 +319,9 @@ void FurnaceGUI::doAction(int what) {
|
|||
case GUI_ACTION_WINDOW_CS_PLAYER:
|
||||
nextWindow=GUI_WINDOW_CS_PLAYER;
|
||||
break;
|
||||
case GUI_ACTION_WINDOW_USER_PRESETS:
|
||||
nextWindow=GUI_WINDOW_USER_PRESETS;
|
||||
break;
|
||||
|
||||
case GUI_ACTION_COLLAPSE_WINDOW:
|
||||
collapseWindow=true;
|
||||
|
|
@ -424,6 +427,8 @@ void FurnaceGUI::doAction(int what) {
|
|||
case GUI_WINDOW_CS_PLAYER:
|
||||
csPlayerOpen=false;
|
||||
break;
|
||||
case GUI_WINDOW_USER_PRESETS:
|
||||
userPresetsOpen=false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -515,10 +520,10 @@ void FurnaceGUI::doAction(int what) {
|
|||
moveCursorBottom(false);
|
||||
break;
|
||||
case GUI_ACTION_PAT_CURSOR_UP_COARSE:
|
||||
moveCursor(0,-16,false);
|
||||
moveCursor(0,-editStepCoarse,false);
|
||||
break;
|
||||
case GUI_ACTION_PAT_CURSOR_DOWN_COARSE:
|
||||
moveCursor(0,16,false);
|
||||
moveCursor(0,editStepCoarse,false);
|
||||
break;
|
||||
case GUI_ACTION_PAT_SELECTION_UP:
|
||||
moveCursor(0,-MAX(1,settings.scrollStep?editStep:1),true);
|
||||
|
|
@ -545,10 +550,22 @@ void FurnaceGUI::doAction(int what) {
|
|||
moveCursorBottom(true);
|
||||
break;
|
||||
case GUI_ACTION_PAT_SELECTION_UP_COARSE:
|
||||
moveCursor(0,-16,true);
|
||||
moveCursor(0,-editStepCoarse,true);
|
||||
break;
|
||||
case GUI_ACTION_PAT_SELECTION_DOWN_COARSE:
|
||||
moveCursor(0,16,true);
|
||||
moveCursor(0,editStepCoarse,true);
|
||||
break;
|
||||
case GUI_ACTION_PAT_MOVE_UP:
|
||||
moveSelected(0,-1);
|
||||
break;
|
||||
case GUI_ACTION_PAT_MOVE_DOWN:
|
||||
moveSelected(0,1);
|
||||
break;
|
||||
case GUI_ACTION_PAT_MOVE_LEFT_CHANNEL:
|
||||
moveSelected(-1,0);
|
||||
break;
|
||||
case GUI_ACTION_PAT_MOVE_RIGHT_CHANNEL:
|
||||
moveSelected(1,0);
|
||||
break;
|
||||
case GUI_ACTION_PAT_DELETE:
|
||||
doDelete();
|
||||
|
|
@ -659,6 +676,17 @@ void FurnaceGUI::doAction(int what) {
|
|||
latchTarget=0;
|
||||
latchNibble=false;
|
||||
break;
|
||||
case GUI_ACTION_PAT_ABSORB_INSTRUMENT: {
|
||||
DivPattern* pat=e->curPat[cursor.xCoarse].getPattern(e->curOrders->ord[cursor.xCoarse][curOrder],false);
|
||||
if (!pat) break;
|
||||
for (int i=cursor.y; i>=0; i--) {
|
||||
if (pat->data[i][2] >= 0) {
|
||||
curIns=pat->data[i][2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GUI_ACTION_INS_LIST_ADD:
|
||||
if (settings.insTypeMenu) {
|
||||
|
|
@ -671,7 +699,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
}
|
||||
curIns=e->addInstrument(cursor.xCoarse);
|
||||
if (curIns==-1) {
|
||||
showError("too many instruments!");
|
||||
showError(_("too many instruments!"));
|
||||
} else {
|
||||
if (settings.blankIns) {
|
||||
e->song.ins[curIns]->fm.fb=0;
|
||||
|
|
@ -689,7 +717,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
e->song.ins[curIns]->esfm.op[i].outLvl=0;
|
||||
}
|
||||
}
|
||||
wantScrollList=true;
|
||||
wantScrollListIns=true;
|
||||
MARK_MODIFIED;
|
||||
wavePreviewInit=true;
|
||||
updateFMPreview=true;
|
||||
|
|
@ -700,10 +728,10 @@ void FurnaceGUI::doAction(int what) {
|
|||
int prevIns=curIns;
|
||||
curIns=e->addInstrument(cursor.xCoarse);
|
||||
if (curIns==-1) {
|
||||
showError("too many instruments!");
|
||||
showError(_("too many instruments!"));
|
||||
} else {
|
||||
(*e->song.ins[curIns])=(*e->song.ins[prevIns]);
|
||||
wantScrollList=true;
|
||||
wantScrollListIns=true;
|
||||
MARK_MODIFIED;
|
||||
wavePreviewInit=true;
|
||||
updateFMPreview=true;
|
||||
|
|
@ -725,21 +753,21 @@ void FurnaceGUI::doAction(int what) {
|
|||
case GUI_ACTION_INS_LIST_MOVE_UP:
|
||||
if (e->moveInsUp(curIns)) {
|
||||
curIns--;
|
||||
wantScrollList=true;
|
||||
wantScrollListIns=true;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
break;
|
||||
case GUI_ACTION_INS_LIST_MOVE_DOWN:
|
||||
if (e->moveInsDown(curIns)) {
|
||||
curIns++;
|
||||
wantScrollList=true;
|
||||
wantScrollListIns=true;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
break;
|
||||
case GUI_ACTION_INS_LIST_DELETE:
|
||||
if (curIns>=0 && curIns<(int)e->song.ins.size()) {
|
||||
e->delInstrument(curIns);
|
||||
wantScrollList=true;
|
||||
wantScrollListIns=true;
|
||||
MARK_MODIFIED;
|
||||
if (curIns>=(int)e->song.ins.size()) {
|
||||
curIns--;
|
||||
|
|
@ -751,25 +779,41 @@ void FurnaceGUI::doAction(int what) {
|
|||
break;
|
||||
case GUI_ACTION_INS_LIST_UP:
|
||||
if (--curIns<0) curIns=0;
|
||||
wantScrollList=true;
|
||||
wantScrollListIns=true;
|
||||
wavePreviewInit=true;
|
||||
updateFMPreview=true;
|
||||
break;
|
||||
case GUI_ACTION_INS_LIST_DOWN:
|
||||
if (++curIns>=(int)e->song.ins.size()) curIns=((int)e->song.ins.size())-1;
|
||||
wantScrollList=true;
|
||||
wantScrollListIns=true;
|
||||
wavePreviewInit=true;
|
||||
updateFMPreview=true;
|
||||
break;
|
||||
case GUI_ACTION_INS_LIST_DIR_VIEW:
|
||||
insListDir=!insListDir;
|
||||
break;
|
||||
case GUI_ACTION_INS_LIST_SAVE_ALL:
|
||||
if (e->song.ins.empty()) {
|
||||
showError(_("this song doesn't have any instruments."));
|
||||
} else {
|
||||
openFileDialog(GUI_FILE_INS_SAVE_ALL);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case GUI_ACTION_WAVE_LIST_ADD: {
|
||||
std::vector<DivSystem> alreadyDone;
|
||||
waveSizeList.clear();
|
||||
for (int i=0; i<e->song.systemLen; i++) {
|
||||
bool skip=false;
|
||||
for (DivSystem j: alreadyDone) {
|
||||
if (e->song.system[i]==j) {
|
||||
skip=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (skip) continue;
|
||||
const DivSysDef* sysDef=e->getSystemDef(e->song.system[i]);
|
||||
alreadyDone.push_back(e->song.system[i]);
|
||||
if (sysDef==NULL) continue;
|
||||
|
||||
if (sysDef->waveHeight==0) continue;
|
||||
|
|
@ -795,9 +839,9 @@ void FurnaceGUI::doAction(int what) {
|
|||
|
||||
curWave=e->addWave();
|
||||
if (curWave==-1) {
|
||||
showError("too many wavetables!");
|
||||
showError(_("too many wavetables!"));
|
||||
} else {
|
||||
wantScrollList=true;
|
||||
wantScrollListWave=true;
|
||||
e->song.wave[curWave]->len=finalWidth;
|
||||
e->song.wave[curWave]->max=finalHeight-1;
|
||||
for (int j=0; j<finalWidth; j++) {
|
||||
|
|
@ -813,10 +857,10 @@ void FurnaceGUI::doAction(int what) {
|
|||
int prevWave=curWave;
|
||||
curWave=e->addWave();
|
||||
if (curWave==-1) {
|
||||
showError("too many wavetables!");
|
||||
showError(_("too many wavetables!"));
|
||||
} else {
|
||||
(*e->song.wave[curWave])=(*e->song.wave[prevWave]);
|
||||
wantScrollList=true;
|
||||
wantScrollListWave=true;
|
||||
MARK_MODIFIED;
|
||||
RESET_WAVE_MACRO_ZOOM;
|
||||
}
|
||||
|
|
@ -840,14 +884,14 @@ void FurnaceGUI::doAction(int what) {
|
|||
case GUI_ACTION_WAVE_LIST_MOVE_UP:
|
||||
if (e->moveWaveUp(curWave)) {
|
||||
curWave--;
|
||||
wantScrollList=true;
|
||||
wantScrollListWave=true;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
break;
|
||||
case GUI_ACTION_WAVE_LIST_MOVE_DOWN:
|
||||
if (e->moveWaveDown(curWave)) {
|
||||
curWave++;
|
||||
wantScrollList=true;
|
||||
wantScrollListWave=true;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
break;
|
||||
|
|
@ -855,7 +899,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
if (curWave>=0 && curWave<(int)e->song.wave.size()) {
|
||||
e->delWave(curWave);
|
||||
MARK_MODIFIED;
|
||||
wantScrollList=true;
|
||||
wantScrollListWave=true;
|
||||
if (curWave>=(int)e->song.wave.size()) {
|
||||
curWave--;
|
||||
}
|
||||
|
|
@ -866,22 +910,29 @@ void FurnaceGUI::doAction(int what) {
|
|||
break;
|
||||
case GUI_ACTION_WAVE_LIST_UP:
|
||||
if (--curWave<0) curWave=0;
|
||||
wantScrollList=true;
|
||||
wantScrollListWave=true;
|
||||
break;
|
||||
case GUI_ACTION_WAVE_LIST_DOWN:
|
||||
if (++curWave>=(int)e->song.wave.size()) curWave=((int)e->song.wave.size())-1;
|
||||
wantScrollList=true;
|
||||
wantScrollListWave=true;
|
||||
break;
|
||||
case GUI_ACTION_WAVE_LIST_DIR_VIEW:
|
||||
waveListDir=!waveListDir;
|
||||
break;
|
||||
case GUI_ACTION_WAVE_LIST_SAVE_ALL:
|
||||
if (e->song.wave.empty()) {
|
||||
showError(_("this song doesn't have any wavetables."));
|
||||
} else {
|
||||
openFileDialog(GUI_FILE_WAVE_SAVE_ALL);
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_ACTION_SAMPLE_LIST_ADD:
|
||||
curSample=e->addSample();
|
||||
if (curSample==-1) {
|
||||
showError("too many samples!");
|
||||
showError(_("too many samples!"));
|
||||
} else {
|
||||
wantScrollList=true;
|
||||
wantScrollListSample=true;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
updateSampleTex=true;
|
||||
|
|
@ -891,7 +942,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
DivSample* prevSample=e->getSample(curSample);
|
||||
curSample=e->addSample();
|
||||
if (curSample==-1) {
|
||||
showError("too many samples!");
|
||||
showError(_("too many samples!"));
|
||||
} else {
|
||||
e->lockEngine([this,prevSample]() {
|
||||
DivSample* sample=e->getSample(curSample);
|
||||
|
|
@ -904,6 +955,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
sample->loop=prevSample->loop;
|
||||
sample->loopMode=prevSample->loopMode;
|
||||
sample->brrEmphasis=prevSample->brrEmphasis;
|
||||
sample->brrNoFilter=prevSample->brrNoFilter;
|
||||
sample->dither=prevSample->dither;
|
||||
sample->depth=prevSample->depth;
|
||||
if (sample->init(prevSample->samples)) {
|
||||
|
|
@ -914,7 +966,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
}
|
||||
e->renderSamples();
|
||||
});
|
||||
wantScrollList=true;
|
||||
wantScrollListSample=true;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
updateSampleTex=true;
|
||||
|
|
@ -941,7 +993,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
case GUI_ACTION_SAMPLE_LIST_MOVE_UP:
|
||||
if (e->moveSampleUp(curSample)) {
|
||||
curSample--;
|
||||
wantScrollList=true;
|
||||
wantScrollListSample=true;
|
||||
updateSampleTex=true;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
|
|
@ -949,14 +1001,14 @@ void FurnaceGUI::doAction(int what) {
|
|||
case GUI_ACTION_SAMPLE_LIST_MOVE_DOWN:
|
||||
if (e->moveSampleDown(curSample)) {
|
||||
curSample++;
|
||||
wantScrollList=true;
|
||||
wantScrollListSample=true;
|
||||
updateSampleTex=true;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
break;
|
||||
case GUI_ACTION_SAMPLE_LIST_DELETE:
|
||||
e->delSample(curSample);
|
||||
wantScrollList=true;
|
||||
wantScrollListSample=true;
|
||||
MARK_MODIFIED;
|
||||
if (curSample>=(int)e->song.sample.size()) {
|
||||
curSample--;
|
||||
|
|
@ -968,12 +1020,12 @@ void FurnaceGUI::doAction(int what) {
|
|||
break;
|
||||
case GUI_ACTION_SAMPLE_LIST_UP:
|
||||
if (--curSample<0) curSample=0;
|
||||
wantScrollList=true;
|
||||
wantScrollListSample=true;
|
||||
updateSampleTex=true;
|
||||
break;
|
||||
case GUI_ACTION_SAMPLE_LIST_DOWN:
|
||||
if (++curSample>=(int)e->song.sample.size()) curSample=((int)e->song.sample.size())-1;
|
||||
wantScrollList=true;
|
||||
wantScrollListSample=true;
|
||||
updateSampleTex=true;
|
||||
break;
|
||||
case GUI_ACTION_SAMPLE_LIST_PREVIEW:
|
||||
|
|
@ -1028,6 +1080,13 @@ void FurnaceGUI::doAction(int what) {
|
|||
displayInsTypeListMakeInsSample=-2;
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_LIST_SAVE_ALL:
|
||||
if (e->song.sample.empty()) {
|
||||
showError(_("this song doesn't have any samples."));
|
||||
} else {
|
||||
openFileDialog(GUI_FILE_SAMPLE_SAVE_ALL);
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_ACTION_SAMPLE_SELECT:
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
|
|
@ -1094,7 +1153,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
|
||||
e->lockEngine([this,sample,pos]() {
|
||||
if (!sample->insert(pos,sampleClipboardLen)) {
|
||||
showError("couldn't paste! make sure your sample is 8 or 16-bit.");
|
||||
showError(_("couldn't paste! make sure your sample is 8 or 16-bit."));
|
||||
} else {
|
||||
if (sample->depth==DIV_SAMPLE_DEPTH_8BIT) {
|
||||
for (size_t i=0; i<sampleClipboardLen; i++) {
|
||||
|
|
@ -1563,7 +1622,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
DivSample* sample=e->song.sample[curSample];
|
||||
curIns=e->addInstrument(cursor.xCoarse);
|
||||
if (curIns==-1) {
|
||||
showError("too many instruments!");
|
||||
showError(_("too many instruments!"));
|
||||
} else {
|
||||
e->song.ins[curIns]->type=insType;
|
||||
e->song.ins[curIns]->name=sample->name;
|
||||
|
|
@ -1598,13 +1657,13 @@ void FurnaceGUI::doAction(int what) {
|
|||
DivSample* sample=e->song.sample[curSample];
|
||||
SAMPLE_OP_BEGIN;
|
||||
if (end-start<1) {
|
||||
showError("select at least one sample!");
|
||||
showError(_("select at least one sample!"));
|
||||
} else if (end-start>256) {
|
||||
showError("maximum size is 256 samples!");
|
||||
showError(_("maximum size is 256 samples!"));
|
||||
} else {
|
||||
curWave=e->addWave();
|
||||
if (curWave==-1) {
|
||||
showError("too many wavetables!");
|
||||
showError(_("too many wavetables!"));
|
||||
} else {
|
||||
DivWavetable* wave=e->song.wave[curWave];
|
||||
wave->min=0;
|
||||
|
|
|
|||
|
|
@ -44,44 +44,44 @@ const float mobileButtonDistances[4][8]={
|
|||
|
||||
const char* mobileButtonLabels[32]={
|
||||
// page 1
|
||||
"cut",
|
||||
"copy",
|
||||
"paste",
|
||||
"delete",
|
||||
"select\nall",
|
||||
"piano",
|
||||
"undo",
|
||||
"redo",
|
||||
_N("cut"),
|
||||
_N("copy"),
|
||||
_N("paste"),
|
||||
_N("delete"),
|
||||
_N("select\nall"),
|
||||
_N("piano"),
|
||||
_N("undo"),
|
||||
_N("redo"),
|
||||
|
||||
// page 2
|
||||
"paste\nmix",
|
||||
"paste\nmix bg",
|
||||
"paste\nins",
|
||||
"paste\nins bg",
|
||||
"paste\nflood",
|
||||
"paste\noverflow",
|
||||
"transpose\nnotes",
|
||||
"transpose\nvalues",
|
||||
_N("paste\nmix"),
|
||||
_N("paste\nmix bg"),
|
||||
_N("paste\nins"),
|
||||
_N("paste\nins bg"),
|
||||
_N("paste\nflood"),
|
||||
_N("paste\noverflow"),
|
||||
_N("transpose\nnotes"),
|
||||
_N("transpose\nvalues"),
|
||||
|
||||
// page 3
|
||||
"change\nins",
|
||||
"find/\nreplace",
|
||||
"collapse",
|
||||
"expand",
|
||||
"flip",
|
||||
"invert",
|
||||
"interpolate",
|
||||
"scale",
|
||||
_N("change\nins"),
|
||||
_N("find/\nreplace"),
|
||||
_N("collapse"),
|
||||
_N("expand"),
|
||||
_N("flip"),
|
||||
_N("invert"),
|
||||
_N("interpolate"),
|
||||
_N("scale"),
|
||||
|
||||
// page 4
|
||||
"fade",
|
||||
"randomize",
|
||||
"opmask",
|
||||
"scroll\nmode",
|
||||
"input\nlatch",
|
||||
"set\nlatch",
|
||||
"clear\nlatch",
|
||||
"clear"
|
||||
_N("fade"),
|
||||
_N("randomize"),
|
||||
_N("opmask"),
|
||||
_N("scroll\nmode"),
|
||||
_N("input\nlatch"),
|
||||
_N("set\nlatch"),
|
||||
_N("clear\nlatch"),
|
||||
_N("clear")
|
||||
};
|
||||
|
||||
const int mobileButtonActions[32]={
|
||||
|
|
@ -130,7 +130,7 @@ const bool mobileButtonPersist[32]={
|
|||
// page 1
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
|
|
@ -293,7 +293,7 @@ void FurnaceGUI::drawMobileControls() {
|
|||
(mobileEditButtonPos.x*canvasW)+cos(buttonDir*2.0*M_PI)*buttonDist*buttonMirrorX*anim,
|
||||
(mobileEditButtonPos.y*canvasH)+sin(buttonDir*2.0*M_PI)*buttonDist*buttonMirrorY*anim
|
||||
));
|
||||
if (ImGui::Button(mobileButtonLabels[i+mobileEditPage*8],mobileEditButtonSize)) {
|
||||
if (ImGui::Button(_(mobileButtonLabels[i+mobileEditPage*8]),mobileEditButtonSize)) {
|
||||
if (mobileButtonActions[i+mobileEditPage*8]) {
|
||||
doAction(mobileButtonActions[i+mobileEditPage*8]);
|
||||
}
|
||||
|
|
@ -330,7 +330,7 @@ void FurnaceGUI::drawMobileControls() {
|
|||
|
||||
ImGui::SetNextWindowPos(portrait?ImVec2(0.0f,((1.0-mobileMenuPos*0.65)*canvasH)-(0.16*canvasW)):ImVec2(0.5*canvasW*mobileMenuPos,0.0f));
|
||||
ImGui::SetNextWindowSize(portrait?ImVec2(canvasW,0.16*canvasW):ImVec2(0.16*canvasH,canvasH));
|
||||
if (ImGui::Begin("Mobile Controls",NULL,ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags)) {
|
||||
if (ImGui::Begin("Mobile Controls",NULL,ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags,_("Mobile Controls"))) {
|
||||
float avail=portrait?ImGui::GetContentRegionAvail().y:ImGui::GetContentRegionAvail().x;
|
||||
ImVec2 buttonSize=ImVec2(avail,avail);
|
||||
const char* mobButtonName=ICON_FA_CHEVRON_RIGHT "##MobileMenu";
|
||||
|
|
@ -405,7 +405,7 @@ void FurnaceGUI::drawMobileControls() {
|
|||
|
||||
ImGui::SetNextWindowPos(portrait?ImVec2(0.0f,((1.0-mobileMenuPos*0.65)*canvasH)):ImVec2(0.5*canvasW*(mobileMenuPos-1.0),0.0f));
|
||||
ImGui::SetNextWindowSize(portrait?ImVec2(canvasW,0.65*canvasH):ImVec2(0.5*canvasW,canvasH));
|
||||
if (ImGui::Begin("Mobile Menu",NULL,ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags)) {
|
||||
if (ImGui::Begin("Mobile Menu",NULL,ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags,_("Mobile Menu"))) {
|
||||
if (ImGui::BeginTable("SceneSel",5)) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,1.0f);
|
||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,1.0f);
|
||||
|
|
@ -418,44 +418,44 @@ void FurnaceGUI::drawMobileControls() {
|
|||
ImVec2 buttonSize=ImGui::GetContentRegionAvail();
|
||||
buttonSize.y=30.0f*dpiScale;
|
||||
|
||||
if (ImGui::Button("Pattern",buttonSize)) {
|
||||
if (ImGui::Button(_("Pattern"),buttonSize)) {
|
||||
mobScene=GUI_SCENE_PATTERN;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Orders",buttonSize)) {
|
||||
if (ImGui::Button(_("Orders"),buttonSize)) {
|
||||
mobScene=GUI_SCENE_ORDERS;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Ins",buttonSize)) {
|
||||
if (ImGui::Button(_("Ins"),buttonSize)) {
|
||||
mobScene=GUI_SCENE_INSTRUMENT;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Wave",buttonSize)) {
|
||||
if (ImGui::Button(_("Wave"),buttonSize)) {
|
||||
mobScene=GUI_SCENE_WAVETABLE;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Sample",buttonSize)) {
|
||||
if (ImGui::Button(_("Sample"),buttonSize)) {
|
||||
mobScene=GUI_SCENE_SAMPLE;
|
||||
}
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Song",buttonSize)) {
|
||||
if (ImGui::Button(_("Song"),buttonSize)) {
|
||||
mobScene=GUI_SCENE_SONG;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Channels",buttonSize)) {
|
||||
if (ImGui::Button(_("Channels"),buttonSize)) {
|
||||
mobScene=GUI_SCENE_CHANNELS;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Chips",buttonSize)) {
|
||||
if (ImGui::Button(_("Chips"),buttonSize)) {
|
||||
mobScene=GUI_SCENE_CHIPS;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Mixer",buttonSize)) {
|
||||
if (ImGui::Button(_("Mixer"),buttonSize)) {
|
||||
mobScene=GUI_SCENE_MIXER;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Other",buttonSize)) {
|
||||
if (ImGui::Button(_("Other"),buttonSize)) {
|
||||
mobScene=GUI_SCENE_OTHER;
|
||||
}
|
||||
ImGui::EndTable();
|
||||
|
|
@ -484,46 +484,36 @@ void FurnaceGUI::drawMobileControls() {
|
|||
}
|
||||
break;
|
||||
case GUI_SCENE_SONG: {
|
||||
if (ImGui::Button("New")) {
|
||||
if (ImGui::Button(_("New"))) {
|
||||
mobileMenuOpen=false;
|
||||
//doAction(GUI_ACTION_NEW);
|
||||
if (modified) {
|
||||
showWarning("Unsaved changes! Save changes before creating a new song?",GUI_WARN_NEW);
|
||||
showWarning(_("Unsaved changes! Save changes before creating a new song?"),GUI_WARN_NEW);
|
||||
} else {
|
||||
displayNew=true;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Open")) {
|
||||
if (ImGui::Button(_("Open"))) {
|
||||
mobileMenuOpen=false;
|
||||
doAction(GUI_ACTION_OPEN);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Save")) {
|
||||
if (ImGui::Button(_("Save"))) {
|
||||
mobileMenuOpen=false;
|
||||
doAction(GUI_ACTION_SAVE);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Save as...")) {
|
||||
if (ImGui::Button(_("Save as..."))) {
|
||||
mobileMenuOpen=false;
|
||||
doAction(GUI_ACTION_SAVE_AS);
|
||||
}
|
||||
|
||||
if (ImGui::Button("1.1+ .dmf")) {
|
||||
mobileMenuOpen=false;
|
||||
openFileDialog(GUI_FILE_SAVE_DMF);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Legacy .dmf")) {
|
||||
mobileMenuOpen=false;
|
||||
openFileDialog(GUI_FILE_SAVE_DMF_LEGACY);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Export")) {
|
||||
if (ImGui::Button(_("Export"))) {
|
||||
doAction(GUI_ACTION_EXPORT);
|
||||
}
|
||||
|
||||
if (ImGui::Button("Restore Backup")) {
|
||||
if (ImGui::Button(_("Restore Backup"))) {
|
||||
mobileMenuOpen=false;
|
||||
doAction(GUI_ACTION_OPEN_BACKUP);
|
||||
}
|
||||
|
|
@ -531,15 +521,15 @@ void FurnaceGUI::drawMobileControls() {
|
|||
ImGui::Separator();
|
||||
|
||||
if (ImGui::BeginTabBar("MobileSong")) {
|
||||
if (ImGui::BeginTabItem("Song Info")) {
|
||||
if (ImGui::BeginTabItem(_("Song Info"))) {
|
||||
drawSongInfo(true);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Subsongs")) {
|
||||
if (ImGui::BeginTabItem(_("Subsongs"))) {
|
||||
drawSubSongs(true);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Speed")) {
|
||||
if (ImGui::BeginTabItem(_("Speed"))) {
|
||||
drawSpeed(true);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
|
@ -548,113 +538,87 @@ void FurnaceGUI::drawMobileControls() {
|
|||
break;
|
||||
}
|
||||
case GUI_SCENE_CHANNELS:
|
||||
ImGui::Text("Channels here...");
|
||||
ImGui::Text(_("Channels here..."));
|
||||
break;
|
||||
case GUI_SCENE_CHIPS:
|
||||
ImGui::Text("Chips here...");
|
||||
ImGui::Text(_("Chips here..."));
|
||||
break;
|
||||
case GUI_SCENE_MIXER:
|
||||
ImGui::Text("What the hell...");
|
||||
ImGui::Text(_("What the hell..."));
|
||||
break;
|
||||
case GUI_SCENE_OTHER: {
|
||||
if (ImGui::Button("Osc")) {
|
||||
if (ImGui::Button(_("Osc"))) {
|
||||
oscOpen=!oscOpen;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("ChanOsc")) {
|
||||
if (ImGui::Button(_("ChanOsc"))) {
|
||||
chanOscOpen=!chanOscOpen;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("RegView")) {
|
||||
if (ImGui::Button(_("RegView"))) {
|
||||
regViewOpen=!regViewOpen;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Stats")) {
|
||||
if (ImGui::Button(_("Stats"))) {
|
||||
statsOpen=!statsOpen;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Grooves")) {
|
||||
if (ImGui::Button(_("Grooves"))) {
|
||||
groovesOpen=!groovesOpen;
|
||||
}
|
||||
if (ImGui::Button("Compat Flags")) {
|
||||
if (ImGui::Button(_("Compat Flags"))) {
|
||||
compatFlagsOpen=!compatFlagsOpen;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("XYOsc")) {
|
||||
if (ImGui::Button(_("XYOsc"))) {
|
||||
xyOscOpen=!xyOscOpen;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Meter")) {
|
||||
if (ImGui::Button(_("Meter"))) {
|
||||
volMeterOpen=!volMeterOpen;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Memory")) {
|
||||
if (ImGui::Button(_("Memory"))) {
|
||||
memoryOpen=!memoryOpen;
|
||||
}
|
||||
|
||||
if (ImGui::Button(_("CV"))) {
|
||||
cvOpen=!cvOpen;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(_("Presets"))) {
|
||||
userPresetsOpen=!userPresetsOpen;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(_("PatManager"))) {
|
||||
patManagerOpen=!patManagerOpen;
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Button("Panic");
|
||||
ImGui::Button(_("Panic"));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Settings")) {
|
||||
if (ImGui::Button(_("Settings"))) {
|
||||
mobileMenuOpen=false;
|
||||
settingsOpen=true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Log")) {
|
||||
if (ImGui::Button(_("Log"))) {
|
||||
logOpen=!logOpen;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Debug")) {
|
||||
if (ImGui::Button(_("Debug"))) {
|
||||
debugOpen=!debugOpen;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("About")) {
|
||||
if (ImGui::Button(_("About"))) {
|
||||
mobileMenuOpen=false;
|
||||
mobileMenuPos=0.0f;
|
||||
aboutOpen=true;
|
||||
}
|
||||
if (ImGui::Button("Shader Editor")) {
|
||||
shaderEditor=!shaderEditor;
|
||||
}
|
||||
if (ImGui::Button("Switch to Desktop Mode")) {
|
||||
if (ImGui::Button(_("Switch to Desktop Mode"))) {
|
||||
toggleMobileUI(!mobileUI);
|
||||
}
|
||||
|
||||
int numAmiga=0;
|
||||
for (int i=0; i<e->song.systemLen; i++) {
|
||||
if (e->song.system[i]==DIV_SYSTEM_AMIGA) numAmiga++;
|
||||
}
|
||||
|
||||
if (numAmiga) {
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -671,7 +635,7 @@ void FurnaceGUI::drawEditControls() {
|
|||
if (!editControlsOpen) return;
|
||||
switch (settings.controlLayout) {
|
||||
case 0: // classic
|
||||
if (ImGui::Begin("Play/Edit Controls",&editControlsOpen,globalWinFlags)) {
|
||||
if (ImGui::Begin("Play/Edit Controls",&editControlsOpen,globalWinFlags,_("Play/Edit Controls"))) {
|
||||
if (ImGui::BeginTable("PlayEditAlign",2)) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch);
|
||||
|
|
@ -679,7 +643,7 @@ void FurnaceGUI::drawEditControls() {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Octave");
|
||||
ImGui::Text(_("Octave"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputInt("##Octave",&curOctave,1,1)) {
|
||||
|
|
@ -696,15 +660,28 @@ void FurnaceGUI::drawEditControls() {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Edit Step");
|
||||
if (ImGui::SmallButton(changeCoarse?_("Coarse Step"):_("Edit Step"))) {
|
||||
changeCoarse=!changeCoarse;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputInt("##EditStep",&editStep,1,1)) {
|
||||
if (editStep>=e->curSubSong->patLen) editStep=e->curSubSong->patLen-1;
|
||||
if (editStep<0) editStep=0;
|
||||
if (changeCoarse) {
|
||||
if (ImGui::InputInt("##CoarseStep",&editStepCoarse,1,1)) {
|
||||
if (editStepCoarse>=e->curSubSong->patLen) editStepCoarse=e->curSubSong->patLen-1;
|
||||
if (editStepCoarse<0) editStepCoarse=0;
|
||||
|
||||
if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) {
|
||||
nextWindow=GUI_WINDOW_PATTERN;
|
||||
if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) {
|
||||
nextWindow=GUI_WINDOW_PATTERN;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ImGui::InputInt("##EditStep",&editStep,1,1)) {
|
||||
if (editStep>=e->curSubSong->patLen) editStep=e->curSubSong->patLen-1;
|
||||
if (editStep<0) editStep=0;
|
||||
|
||||
if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) {
|
||||
nextWindow=GUI_WINDOW_PATTERN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -716,7 +693,7 @@ void FurnaceGUI::drawEditControls() {
|
|||
play();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Play");
|
||||
ImGui::SetTooltip(_("Play"));
|
||||
}
|
||||
popToggleColors();
|
||||
ImGui::SameLine();
|
||||
|
|
@ -724,25 +701,25 @@ void FurnaceGUI::drawEditControls() {
|
|||
stop();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Stop");
|
||||
ImGui::SetTooltip(_("Stop"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Edit",&edit);
|
||||
ImGui::Checkbox(_("Edit"),&edit);
|
||||
ImGui::SameLine();
|
||||
bool metro=e->getMetronome();
|
||||
if (ImGui::Checkbox("Metronome",&metro)) {
|
||||
if (ImGui::Checkbox(_("Metronome"),&metro)) {
|
||||
e->setMetronome(metro);
|
||||
}
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Follow");
|
||||
ImGui::Text(_("Follow"));
|
||||
ImGui::SameLine();
|
||||
unimportant(ImGui::Checkbox("Orders",&followOrders));
|
||||
unimportant(ImGui::Checkbox(_("Orders"),&followOrders));
|
||||
ImGui::SameLine();
|
||||
unimportant(ImGui::Checkbox("Pattern",&followPattern));
|
||||
unimportant(ImGui::Checkbox(_("Pattern"),&followPattern));
|
||||
|
||||
bool repeatPattern=e->getRepeatPattern();
|
||||
if (ImGui::Checkbox("Repeat pattern",&repeatPattern)) {
|
||||
if (ImGui::Checkbox(_("Repeat pattern"),&repeatPattern)) {
|
||||
e->setRepeatPattern(repeatPattern);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
|
@ -751,17 +728,17 @@ void FurnaceGUI::drawEditControls() {
|
|||
pendingStepUpdate=1;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Step one row");
|
||||
ImGui::SetTooltip(_("Step one row"));
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
pushToggleColors(noteInputPoly);
|
||||
if (ImGui::Button(noteInputPoly?("Poly##PolyInput"):("Mono##PolyInput"))) {
|
||||
if (ImGui::Button(noteInputPoly?(_("Poly##PolyInput")):(_("Mono##PolyInput")))) {
|
||||
noteInputPoly=!noteInputPoly;
|
||||
e->setAutoNotePoly(noteInputPoly);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Polyphony");
|
||||
ImGui::SetTooltip(_("Polyphony"));
|
||||
}
|
||||
popToggleColors();
|
||||
}
|
||||
|
|
@ -769,12 +746,12 @@ void FurnaceGUI::drawEditControls() {
|
|||
ImGui::End();
|
||||
break;
|
||||
case 1: // compact
|
||||
if (ImGui::Begin("Play/Edit Controls",&editControlsOpen,ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags)) {
|
||||
if (ImGui::Begin("Play/Edit Controls",&editControlsOpen,ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags,_("Play/Edit Controls"))) {
|
||||
if (ImGui::Button(ICON_FA_STOP "##Stop")) {
|
||||
stop();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Stop");
|
||||
ImGui::SetTooltip(_("Stop"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
pushToggleColors(e->isPlaying());
|
||||
|
|
@ -782,7 +759,7 @@ void FurnaceGUI::drawEditControls() {
|
|||
play();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Play");
|
||||
ImGui::SetTooltip(_("Play"));
|
||||
}
|
||||
popToggleColors();
|
||||
ImGui::SameLine();
|
||||
|
|
@ -791,7 +768,7 @@ void FurnaceGUI::drawEditControls() {
|
|||
pendingStepUpdate=1;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Step one row");
|
||||
ImGui::SetTooltip(_("Step one row"));
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
|
@ -801,7 +778,7 @@ void FurnaceGUI::drawEditControls() {
|
|||
e->setRepeatPattern(!repeatPattern);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Repeat pattern");
|
||||
ImGui::SetTooltip(_("Repeat pattern"));
|
||||
}
|
||||
popToggleColors();
|
||||
|
||||
|
|
@ -811,7 +788,7 @@ void FurnaceGUI::drawEditControls() {
|
|||
edit=!edit;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Edit");
|
||||
ImGui::SetTooltip(_("Edit"));
|
||||
}
|
||||
popToggleColors();
|
||||
|
||||
|
|
@ -822,12 +799,12 @@ void FurnaceGUI::drawEditControls() {
|
|||
e->setMetronome(!metro);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Metronome");
|
||||
ImGui::SetTooltip(_("Metronome"));
|
||||
}
|
||||
popToggleColors();
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("Octave");
|
||||
ImGui::Text(_("Octave"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(96.0f*dpiScale);
|
||||
if (ImGui::InputInt("##Octave",&curOctave,1,1)) {
|
||||
|
|
@ -842,33 +819,46 @@ void FurnaceGUI::drawEditControls() {
|
|||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("Edit Step");
|
||||
if (ImGui::SmallButton(changeCoarse?_("Coarse Step"):_("Edit Step"))) {
|
||||
changeCoarse=!changeCoarse;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(96.0f*dpiScale);
|
||||
if (ImGui::InputInt("##EditStep",&editStep,1,1)) {
|
||||
if (editStep>=e->curSubSong->patLen) editStep=e->curSubSong->patLen-1;
|
||||
if (editStep<0) editStep=0;
|
||||
if (changeCoarse) {
|
||||
if (ImGui::InputInt("##CoarseStep",&editStepCoarse,1,1)) {
|
||||
if (editStepCoarse>=e->curSubSong->patLen) editStepCoarse=e->curSubSong->patLen-1;
|
||||
if (editStepCoarse<0) editStepCoarse=0;
|
||||
|
||||
if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) {
|
||||
nextWindow=GUI_WINDOW_PATTERN;
|
||||
if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) {
|
||||
nextWindow=GUI_WINDOW_PATTERN;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ImGui::InputInt("##EditStep",&editStep,1,1)) {
|
||||
if (editStep>=e->curSubSong->patLen) editStep=e->curSubSong->patLen-1;
|
||||
if (editStep<0) editStep=0;
|
||||
|
||||
if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) {
|
||||
nextWindow=GUI_WINDOW_PATTERN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("Follow");
|
||||
ImGui::Text(_("Follow"));
|
||||
ImGui::SameLine();
|
||||
unimportant(ImGui::Checkbox("Orders",&followOrders));
|
||||
unimportant(ImGui::Checkbox(_("Orders"),&followOrders));
|
||||
ImGui::SameLine();
|
||||
unimportant(ImGui::Checkbox("Pattern",&followPattern));
|
||||
unimportant(ImGui::Checkbox(_("Pattern"),&followPattern));
|
||||
|
||||
ImGui::SameLine();
|
||||
pushToggleColors(noteInputPoly);
|
||||
if (ImGui::Button(noteInputPoly?("Poly##PolyInput"):("Mono##PolyInput"))) {
|
||||
if (ImGui::Button(noteInputPoly?_("Poly##PolyInput"):_("Mono##PolyInput"))) {
|
||||
noteInputPoly=!noteInputPoly;
|
||||
e->setAutoNotePoly(noteInputPoly);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Polyphony");
|
||||
ImGui::SetTooltip(_("Polyphony"));
|
||||
}
|
||||
popToggleColors();
|
||||
}
|
||||
|
|
@ -876,28 +866,28 @@ void FurnaceGUI::drawEditControls() {
|
|||
ImGui::End();
|
||||
break;
|
||||
case 2: // compact vertical
|
||||
if (ImGui::Begin("Play/Edit Controls",&editControlsOpen,ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags)) {
|
||||
if (ImGui::Begin("Play/Edit Controls",&editControlsOpen,ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags,_("Play/Edit Controls"))) {
|
||||
ImVec2 buttonSize=ImVec2(ImGui::GetContentRegionAvail().x,0.0f);
|
||||
pushToggleColors(e->isPlaying());
|
||||
if (ImGui::Button(ICON_FA_PLAY "##Play",buttonSize)) {
|
||||
play();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Play");
|
||||
ImGui::SetTooltip(_("Play"));
|
||||
}
|
||||
popToggleColors();
|
||||
if (ImGui::Button(ICON_FA_STOP "##Stop",buttonSize)) {
|
||||
stop();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Stop");
|
||||
ImGui::SetTooltip(_("Stop"));
|
||||
}
|
||||
if (ImGui::Button(ICON_FA_ARROW_DOWN "##StepOne",buttonSize)) {
|
||||
e->stepOne(cursor.y);
|
||||
pendingStepUpdate=1;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Step one row");
|
||||
ImGui::SetTooltip(_("Step one row"));
|
||||
}
|
||||
|
||||
bool repeatPattern=e->getRepeatPattern();
|
||||
|
|
@ -906,7 +896,7 @@ void FurnaceGUI::drawEditControls() {
|
|||
e->setRepeatPattern(!repeatPattern);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Repeat pattern");
|
||||
ImGui::SetTooltip(_("Repeat pattern"));
|
||||
}
|
||||
popToggleColors();
|
||||
|
||||
|
|
@ -915,7 +905,7 @@ void FurnaceGUI::drawEditControls() {
|
|||
edit=!edit;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Edit");
|
||||
ImGui::SetTooltip(_("Edit"));
|
||||
}
|
||||
popToggleColors();
|
||||
|
||||
|
|
@ -925,13 +915,13 @@ void FurnaceGUI::drawEditControls() {
|
|||
e->setMetronome(!metro);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Metronome");
|
||||
ImGui::SetTooltip(_("Metronome"));
|
||||
}
|
||||
popToggleColors();
|
||||
|
||||
ImGui::Text("Oct.");
|
||||
ImGui::Text(_("Oct."));
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Octave");
|
||||
ImGui::SetTooltip(_("Octave"));
|
||||
}
|
||||
float avail=ImGui::GetContentRegionAvail().x;
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
|
|
@ -946,45 +936,58 @@ void FurnaceGUI::drawEditControls() {
|
|||
}
|
||||
}
|
||||
|
||||
ImGui::Text("Step");
|
||||
if (ImGui::SmallButton(changeCoarse?_("Coarse"):_("Step"))) {
|
||||
changeCoarse=!changeCoarse;
|
||||
}
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
if (ImGui::InputInt("##EditStep",&editStep,0,0)) {
|
||||
if (editStep>=e->curSubSong->patLen) editStep=e->curSubSong->patLen-1;
|
||||
if (editStep<0) editStep=0;
|
||||
if (changeCoarse) {
|
||||
if (ImGui::InputInt("##CoarseStep",&editStepCoarse,1,1)) {
|
||||
if (editStepCoarse>=e->curSubSong->patLen) editStepCoarse=e->curSubSong->patLen-1;
|
||||
if (editStepCoarse<0) editStepCoarse=0;
|
||||
|
||||
if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) {
|
||||
nextWindow=GUI_WINDOW_PATTERN;
|
||||
if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) {
|
||||
nextWindow=GUI_WINDOW_PATTERN;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ImGui::InputInt("##EditStep",&editStep,0,0)) {
|
||||
if (editStep>=e->curSubSong->patLen) editStep=e->curSubSong->patLen-1;
|
||||
if (editStep<0) editStep=0;
|
||||
|
||||
if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) {
|
||||
nextWindow=GUI_WINDOW_PATTERN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Text("Foll.");
|
||||
ImGui::Text(_("Foll."));
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Follow");
|
||||
ImGui::SetTooltip(_("Follow"));
|
||||
}
|
||||
pushToggleColors(followOrders);
|
||||
if (ImGui::Button("Ord##FollowOrders",buttonSize)) { handleUnimportant
|
||||
if (ImGui::Button(_("Ord##FollowOrders"),buttonSize)) { handleUnimportant
|
||||
followOrders=!followOrders;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Orders");
|
||||
ImGui::SetTooltip(_("Orders"));
|
||||
}
|
||||
popToggleColors();
|
||||
pushToggleColors(followPattern);
|
||||
if (ImGui::Button("Pat##FollowPattern",buttonSize)) { handleUnimportant
|
||||
if (ImGui::Button(_("Pat##FollowPattern"),buttonSize)) { handleUnimportant
|
||||
followPattern=!followPattern;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Pattern");
|
||||
ImGui::SetTooltip(_("Pattern"));
|
||||
}
|
||||
popToggleColors();
|
||||
|
||||
pushToggleColors(noteInputPoly);
|
||||
if (ImGui::Button(noteInputPoly?("Poly##PolyInput"):("Mono##PolyInput"))) {
|
||||
if (ImGui::Button(noteInputPoly?_("Poly##PolyInput"):_("Mono##PolyInput"))) {
|
||||
noteInputPoly=!noteInputPoly;
|
||||
e->setAutoNotePoly(noteInputPoly);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Polyphony");
|
||||
ImGui::SetTooltip(_("Polyphony"));
|
||||
}
|
||||
popToggleColors();
|
||||
}
|
||||
|
|
@ -992,14 +995,14 @@ void FurnaceGUI::drawEditControls() {
|
|||
ImGui::End();
|
||||
break;
|
||||
case 3: // split
|
||||
if (ImGui::Begin("Play Controls",&editControlsOpen,ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags)) {
|
||||
if (ImGui::Begin("Play Controls",&editControlsOpen,ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags,_("Play Controls"))) {
|
||||
if (e->isPlaying()) {
|
||||
pushToggleColors(true);
|
||||
if (ImGui::Button(ICON_FA_STOP "##Stop")) {
|
||||
stop();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Stop");
|
||||
ImGui::SetTooltip(_("Stop"));
|
||||
}
|
||||
popToggleColors();
|
||||
} else {
|
||||
|
|
@ -1007,7 +1010,7 @@ void FurnaceGUI::drawEditControls() {
|
|||
play(oldRow);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Play");
|
||||
ImGui::SetTooltip(_("Play"));
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
|
@ -1016,7 +1019,7 @@ void FurnaceGUI::drawEditControls() {
|
|||
play();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Play from the beginning of this pattern");
|
||||
ImGui::SetTooltip(_("Play from the beginning of this pattern"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_STEP_FORWARD "##PlayRepeat")) {
|
||||
|
|
@ -1024,7 +1027,7 @@ void FurnaceGUI::drawEditControls() {
|
|||
play();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Repeat from the beginning of this pattern");
|
||||
ImGui::SetTooltip(_("Repeat from the beginning of this pattern"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_ARROW_DOWN "##StepOne")) {
|
||||
|
|
@ -1032,7 +1035,7 @@ void FurnaceGUI::drawEditControls() {
|
|||
pendingStepUpdate=1;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Step one row");
|
||||
ImGui::SetTooltip(_("Step one row"));
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
|
@ -1041,7 +1044,7 @@ void FurnaceGUI::drawEditControls() {
|
|||
edit=!edit;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Edit");
|
||||
ImGui::SetTooltip(_("Edit"));
|
||||
}
|
||||
popToggleColors();
|
||||
|
||||
|
|
@ -1052,7 +1055,7 @@ void FurnaceGUI::drawEditControls() {
|
|||
e->setMetronome(!metro);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Metronome");
|
||||
ImGui::SetTooltip(_("Metronome"));
|
||||
}
|
||||
popToggleColors();
|
||||
|
||||
|
|
@ -1063,28 +1066,28 @@ void FurnaceGUI::drawEditControls() {
|
|||
e->setRepeatPattern(!repeatPattern);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Repeat pattern");
|
||||
ImGui::SetTooltip(_("Repeat pattern"));
|
||||
}
|
||||
popToggleColors();
|
||||
|
||||
ImGui::SameLine();
|
||||
pushToggleColors(noteInputPoly);
|
||||
if (ImGui::Button(noteInputPoly?("Poly##PolyInput"):("Mono##PolyInput"))) {
|
||||
if (ImGui::Button(noteInputPoly?_("Poly##PolyInput"):_("Mono##PolyInput"))) {
|
||||
noteInputPoly=!noteInputPoly;
|
||||
e->setAutoNotePoly(noteInputPoly);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Polyphony");
|
||||
ImGui::SetTooltip(_("Polyphony"));
|
||||
}
|
||||
popToggleColors();
|
||||
}
|
||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_EDIT_CONTROLS;
|
||||
ImGui::End();
|
||||
|
||||
if (ImGui::Begin("Edit Controls",&editControlsOpen,globalWinFlags)) {
|
||||
if (ImGui::Begin("Edit Controls",&editControlsOpen,globalWinFlags,_("Edit Controls"))) {
|
||||
ImGui::Columns(2);
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Octave");
|
||||
ImGui::Text(_("Octave"));
|
||||
ImGui::SameLine();
|
||||
float cursor=ImGui::GetCursorPosX();
|
||||
float avail=ImGui::GetContentRegionAvail().x;
|
||||
|
|
@ -1101,22 +1104,35 @@ void FurnaceGUI::drawEditControls() {
|
|||
}
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Step");
|
||||
if (ImGui::SmallButton(changeCoarse?_("Coarse"):_("Step"))) {
|
||||
changeCoarse=!changeCoarse;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(cursor);
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
if (ImGui::InputInt("##EditStep",&editStep,1,1)) {
|
||||
if (editStep>=e->curSubSong->patLen) editStep=e->curSubSong->patLen-1;
|
||||
if (editStep<0) editStep=0;
|
||||
if (changeCoarse) {
|
||||
if (ImGui::InputInt("##CoarseStep",&editStepCoarse,1,1)) {
|
||||
if (editStepCoarse>=e->curSubSong->patLen) editStepCoarse=e->curSubSong->patLen-1;
|
||||
if (editStepCoarse<0) editStepCoarse=0;
|
||||
|
||||
if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) {
|
||||
nextWindow=GUI_WINDOW_PATTERN;
|
||||
if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) {
|
||||
nextWindow=GUI_WINDOW_PATTERN;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ImGui::InputInt("##EditStep",&editStep,1,1)) {
|
||||
if (editStep>=e->curSubSong->patLen) editStep=e->curSubSong->patLen-1;
|
||||
if (editStep<0) editStep=0;
|
||||
|
||||
if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) {
|
||||
nextWindow=GUI_WINDOW_PATTERN;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::NextColumn();
|
||||
|
||||
unimportant(ImGui::Checkbox("Follow orders",&followOrders));
|
||||
unimportant(ImGui::Checkbox("Follow pattern",&followPattern));
|
||||
unimportant(ImGui::Checkbox(_("Follow orders"),&followOrders));
|
||||
unimportant(ImGui::Checkbox(_("Follow pattern"),&followPattern));
|
||||
}
|
||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_EDIT_CONTROLS;
|
||||
ImGui::End();
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ void FurnaceGUI::makeUndo(ActionType action, UndoRegion region) {
|
|||
|
||||
auto it=oldPatMap.find(id);
|
||||
if (it==oldPatMap.end()) {
|
||||
logW("no data in oldPatMap for channel %d!",i);
|
||||
logW(_("no data in oldPatMap for channel %d!"),i);
|
||||
continue;
|
||||
} else {
|
||||
op=it->second;
|
||||
|
|
@ -661,7 +661,7 @@ void FurnaceGUI::doPasteFurnace(PasteMode mode, int arg, bool readClipboard, Str
|
|||
}
|
||||
|
||||
if (invalidData) {
|
||||
logW("invalid clipboard data! failed at line %d char %d",i,charPos);
|
||||
logW(_("invalid clipboard data! failed at line %d char %d"),i,charPos);
|
||||
logW("%s",line.c_str());
|
||||
break;
|
||||
}
|
||||
|
|
@ -1200,7 +1200,7 @@ void FurnaceGUI::doPasteMPT(PasteMode mode, int arg, bool readClipboard, String
|
|||
|
||||
if (invalidData)
|
||||
{
|
||||
logW("invalid clipboard data! failed at line %d char %d",i,charPos);
|
||||
logW(_("invalid clipboard data! failed at line %d char %d"),i,charPos);
|
||||
logW("%s",line.c_str());
|
||||
break;
|
||||
}
|
||||
|
|
@ -1562,7 +1562,7 @@ void FurnaceGUI::doFlip() {
|
|||
void FurnaceGUI::doCollapse(int divider, const SelectionPoint& sStart, const SelectionPoint& sEnd) {
|
||||
if (divider<2) return;
|
||||
if (e->curSubSong->patLen<divider) {
|
||||
showError("can't collapse any further!");
|
||||
showError(_("can't collapse any further!"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1666,7 +1666,7 @@ void FurnaceGUI::doExpand(int multiplier, const SelectionPoint& sStart, const Se
|
|||
void FurnaceGUI::doCollapseSong(int divider) {
|
||||
if (divider<2) return;
|
||||
if (e->curSubSong->patLen<divider) {
|
||||
showError("can't collapse any further!");
|
||||
showError(_("can't collapse any further!"));
|
||||
return;
|
||||
}
|
||||
finishSelection();
|
||||
|
|
@ -1746,7 +1746,7 @@ void FurnaceGUI::doCollapseSong(int divider) {
|
|||
void FurnaceGUI::doExpandSong(int multiplier) {
|
||||
if (multiplier<2) return;
|
||||
if (e->curSubSong->patLen>(256/multiplier)) {
|
||||
showError("can't expand any further!");
|
||||
showError(_("can't expand any further!"));
|
||||
return;
|
||||
}
|
||||
finishSelection();
|
||||
|
|
@ -1833,7 +1833,7 @@ void FurnaceGUI::doDrag() {
|
|||
// copy and clear
|
||||
String c=doCopy(true,false,dragStart,dragEnd);
|
||||
|
||||
logV("copy: %s",c);
|
||||
logV(_("copy: %s"),c);
|
||||
|
||||
// replace
|
||||
cursor=selStart;
|
||||
|
|
@ -1842,6 +1842,25 @@ void FurnaceGUI::doDrag() {
|
|||
makeUndo(GUI_UNDO_PATTERN_DRAG);
|
||||
}
|
||||
|
||||
void FurnaceGUI::moveSelected(int x, int y) {
|
||||
prepareUndo(GUI_UNDO_PATTERN_DRAG);
|
||||
|
||||
// copy and clear
|
||||
String c=doCopy(true,false,selStart,selEnd);
|
||||
|
||||
logV(_("copy: %s"),c);
|
||||
|
||||
// replace
|
||||
selStart.xCoarse+=x;
|
||||
selEnd.xCoarse+=x;
|
||||
selStart.y+=y;
|
||||
selEnd.y+=y;
|
||||
cursor=selStart;
|
||||
doPaste(GUI_PASTE_MODE_NORMAL,0,false,c);
|
||||
|
||||
makeUndo(GUI_UNDO_PATTERN_DRAG);
|
||||
}
|
||||
|
||||
void FurnaceGUI::doUndo() {
|
||||
if (undoHist.empty()) return;
|
||||
UndoStep& us=undoHist.back();
|
||||
|
|
|
|||
|
|
@ -11,27 +11,27 @@ void FurnaceGUI::drawEffectList() {
|
|||
}
|
||||
if (!effectListOpen) return;
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(60.0f*dpiScale,20.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||
if (ImGui::Begin("Effect List",&effectListOpen,globalWinFlags)) {
|
||||
if (ImGui::Begin("Effect List",&effectListOpen,globalWinFlags,_("Effect List"))) {
|
||||
float availB=ImGui::GetContentRegionAvail().x-ImGui::GetFrameHeightWithSpacing();
|
||||
if (availB>0) {
|
||||
ImGui::PushTextWrapPos(availB);
|
||||
ImGui::TextWrapped("Chip at cursor: %s",e->getSystemName(e->sysOfChan[cursor.xCoarse]));
|
||||
ImGui::TextWrapped(_("Chip at cursor: %s"),e->getSystemName(e->sysOfChan[cursor.xCoarse]));
|
||||
ImGui::PopTextWrapPos();
|
||||
}
|
||||
effectSearch.Draw("Search");
|
||||
effectSearch.Draw(_("Search"));
|
||||
ImGui::SameLine();
|
||||
ImGui::Button(ICON_FA_BARS "##SortEffects");
|
||||
if (ImGui::BeginPopupContextItem("effectSort",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
ImGui::Text("Effect types to show:");
|
||||
ImGui::Text(_("Effect types to show:"));
|
||||
for (int i=1; i<10; i++) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[i+GUI_COLOR_PATTERN_EFFECT_INVALID]);
|
||||
ImGui::Checkbox(fxColorsNames[i],&effectsShow[i]);
|
||||
ImGui::Checkbox(_(fxColorsNames[i]),&effectsShow[i]);
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
if (ImGui::Button("All")) memset(effectsShow,1,sizeof(bool)*10);
|
||||
if (ImGui::Button(_("All"))) memset(effectsShow,1,sizeof(bool)*10);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("None")) memset(effectsShow,0,sizeof(bool)*10);
|
||||
if (ImGui::Button(_("None"))) memset(effectsShow,0,sizeof(bool)*10);
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
|
@ -42,9 +42,9 @@ void FurnaceGUI::drawEffectList() {
|
|||
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Name");
|
||||
ImGui::Text(_("Name"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Description");
|
||||
ImGui::Text(_("Description"));
|
||||
|
||||
const char* prevName=NULL;
|
||||
for (int i=0; i<256; i++) {
|
||||
|
|
@ -81,7 +81,7 @@ void FurnaceGUI::drawEffectList() {
|
|||
if (strlen(name)>6) {
|
||||
ImGui::TextWrapped("%s",&name[6]);
|
||||
} else {
|
||||
ImGui::Text("ERROR");
|
||||
ImGui::Text(_("ERROR"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,43 +26,128 @@
|
|||
void FurnaceGUI::drawExportAudio(bool onWindow) {
|
||||
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;
|
||||
ImGui::Text(_("Export type:"));
|
||||
|
||||
ImGui::Indent();
|
||||
if (ImGui::RadioButton(_("one file"),audioExportOptions.mode==DIV_EXPORT_MODE_ONE)) {
|
||||
audioExportOptions.mode=DIV_EXPORT_MODE_ONE;
|
||||
}
|
||||
if (ImGui::InputDouble("Fade out (seconds)",&exportFadeOut,1.0,2.0,"%.1f")) {
|
||||
if (exportFadeOut<0.0) exportFadeOut=0.0;
|
||||
if (ImGui::RadioButton(_("multiple files (one per chip)"),audioExportOptions.mode==DIV_EXPORT_MODE_MANY_SYS)) {
|
||||
audioExportOptions.mode=DIV_EXPORT_MODE_MANY_SYS;
|
||||
}
|
||||
if (ImGui::RadioButton(_("multiple files (one per channel)"),audioExportOptions.mode==DIV_EXPORT_MODE_MANY_CHAN)) {
|
||||
audioExportOptions.mode=DIV_EXPORT_MODE_MANY_CHAN;
|
||||
}
|
||||
ImGui::Unindent();
|
||||
|
||||
if (audioExportOptions.mode!=DIV_EXPORT_MODE_MANY_SYS) {
|
||||
ImGui::Text(_("Bit depth:"));
|
||||
ImGui::Indent();
|
||||
if (ImGui::RadioButton(_("16-bit integer"),audioExportOptions.format==DIV_EXPORT_FORMAT_S16)) {
|
||||
audioExportOptions.format=DIV_EXPORT_FORMAT_S16;
|
||||
}
|
||||
if (ImGui::RadioButton(_("32-bit float"),audioExportOptions.format==DIV_EXPORT_FORMAT_F32)) {
|
||||
audioExportOptions.format=DIV_EXPORT_FORMAT_F32;
|
||||
}
|
||||
ImGui::Unindent();
|
||||
}
|
||||
|
||||
if (ImGui::InputInt(_("Sample rate"),&audioExportOptions.sampleRate,100,10000)) {
|
||||
if (audioExportOptions.sampleRate<8000) audioExportOptions.sampleRate=8000;
|
||||
if (audioExportOptions.sampleRate>384000) audioExportOptions.sampleRate=384000;
|
||||
}
|
||||
|
||||
if (audioExportOptions.mode!=DIV_EXPORT_MODE_MANY_SYS) {
|
||||
if (ImGui::InputInt(_("Channels in file"),&audioExportOptions.chans,1,1)) {
|
||||
if (audioExportOptions.chans<1) audioExportOptions.chans=1;
|
||||
if (audioExportOptions.chans>16) audioExportOptions.chans=16;
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::InputInt(_("Loops"),&audioExportOptions.loops,1,2)) {
|
||||
if (audioExportOptions.loops<0) audioExportOptions.loops=0;
|
||||
}
|
||||
if (ImGui::InputDouble(_("Fade out (seconds)"),&audioExportOptions.fadeOut,1.0,2.0,"%.1f")) {
|
||||
if (audioExportOptions.fadeOut<0.0) audioExportOptions.fadeOut=0.0;
|
||||
}
|
||||
|
||||
bool isOneOn=false;
|
||||
if (audioExportOptions.mode==DIV_EXPORT_MODE_MANY_CHAN) {
|
||||
ImGui::Text(_("Channels to export:"));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton(_("All"))) {
|
||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
audioExportOptions.channelMask[i]=true;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton(_("None"))) {
|
||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
audioExportOptions.channelMask[i]=false;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton(_("Shown in pattern"))) {
|
||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
audioExportOptions.channelMask[i]=e->curSubSong->chanShow[i];
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton(_("Shown in oscilloscope"))) {
|
||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
audioExportOptions.channelMask[i]=e->curSubSong->chanShowChanOsc[i];
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton(_("Invert"))) {
|
||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
audioExportOptions.channelMask[i]=!audioExportOptions.channelMask[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::BeginChild("Channel Selection",ImVec2(0,200.0f*dpiScale))) {
|
||||
for (int i=0; i<e->getTotalChannelCount(); i++) {
|
||||
String name=fmt::sprintf("%d. %s##_CE%d",i+1,e->getChannelName(i),i);
|
||||
ImGui::Checkbox(name.c_str(),&audioExportOptions.channelMask[i]);
|
||||
if (audioExportOptions.channelMask[i]) isOneOn=true;
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
} else {
|
||||
isOneOn=true;
|
||||
}
|
||||
|
||||
if (onWindow) {
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("Cancel",ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||
if (ImGui::Button(_("Cancel"),ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
if (ImGui::Button("Export",ImVec2(200.0f*dpiScale,0))) {
|
||||
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;
|
||||
if (isOneOn) {
|
||||
if (ImGui::Button(_("Export"),ImVec2(200.0f*dpiScale,0))) {
|
||||
switch (audioExportOptions.mode) {
|
||||
case DIV_EXPORT_MODE_ONE:
|
||||
openFileDialog(GUI_FILE_EXPORT_AUDIO_ONE);
|
||||
break;
|
||||
case DIV_EXPORT_MODE_MANY_SYS:
|
||||
openFileDialog(GUI_FILE_EXPORT_AUDIO_PER_SYS);
|
||||
break;
|
||||
case DIV_EXPORT_MODE_MANY_CHAN:
|
||||
openFileDialog(GUI_FILE_EXPORT_AUDIO_PER_CHANNEL);
|
||||
break;
|
||||
}
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::CloseCurrentPopup();
|
||||
} else {
|
||||
ImGui::Text(_("select at least one channel"));
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::drawExportVGM(bool onWindow) {
|
||||
exitDisabledTimer=1;
|
||||
|
||||
ImGui::Text("settings:");
|
||||
if (ImGui::BeginCombo("format version",fmt::sprintf("%d.%.2x",vgmExportVersion>>8,vgmExportVersion&0xff).c_str())) {
|
||||
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];
|
||||
|
|
@ -70,17 +155,17 @@ void FurnaceGUI::drawExportVGM(bool onWindow) {
|
|||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::Checkbox("loop",&vgmExportLoop);
|
||||
ImGui::Checkbox(_("loop"),&vgmExportLoop);
|
||||
if (vgmExportLoop && e->song.loopModality==2) {
|
||||
ImGui::Text("loop trail:");
|
||||
ImGui::Text(_("loop trail:"));
|
||||
ImGui::Indent();
|
||||
if (ImGui::RadioButton("auto-detect",vgmExportTrailingTicks==-1)) {
|
||||
if (ImGui::RadioButton(_("auto-detect"),vgmExportTrailingTicks==-1)) {
|
||||
vgmExportTrailingTicks=-1;
|
||||
}
|
||||
if (ImGui::RadioButton("add one loop",vgmExportTrailingTicks==-2)) {
|
||||
if (ImGui::RadioButton(_("add one loop"),vgmExportTrailingTicks==-2)) {
|
||||
vgmExportTrailingTicks=-2;
|
||||
}
|
||||
if (ImGui::RadioButton("custom",vgmExportTrailingTicks>=0)) {
|
||||
if (ImGui::RadioButton(_("custom"),vgmExportTrailingTicks>=0)) {
|
||||
vgmExportTrailingTicks=0;
|
||||
}
|
||||
if (vgmExportTrailingTicks>=0) {
|
||||
|
|
@ -91,9 +176,9 @@ void FurnaceGUI::drawExportVGM(bool onWindow) {
|
|||
}
|
||||
ImGui::Unindent();
|
||||
}
|
||||
ImGui::Checkbox("add pattern change hints",&vgmExportPatternHints);
|
||||
ImGui::Checkbox(_("add pattern change hints"),&vgmExportPatternHints);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip(
|
||||
ImGui::SetTooltip(_(
|
||||
"inserts data blocks on pattern changes.\n"
|
||||
"useful if you are writing a playback routine.\n\n"
|
||||
|
||||
|
|
@ -105,17 +190,17 @@ void FurnaceGUI::drawExportVGM(bool onWindow) {
|
|||
"- pp: pattern index (one per channel)\n\n"
|
||||
|
||||
"pattern indexes are ordered as they appear in the song."
|
||||
);
|
||||
));
|
||||
}
|
||||
ImGui::Checkbox("direct stream mode",&vgmExportDirectStream);
|
||||
ImGui::Checkbox(_("direct stream mode"),&vgmExportDirectStream);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip(
|
||||
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:");
|
||||
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]);
|
||||
|
|
@ -124,107 +209,171 @@ void FurnaceGUI::drawExportVGM(bool onWindow) {
|
|||
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);
|
||||
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!");
|
||||
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);
|
||||
ImGui::Text(_("select the chip you wish to export, but only up to %d of each type."),(vgmExportVersion>=0x151)?2:1);
|
||||
if (hasOneAtLeast) {
|
||||
if (onWindow) {
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("Cancel",ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||
if (ImGui::Button(_("Cancel"),ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||
ImGui::SameLine();
|
||||
}
|
||||
if (ImGui::Button("Export",ImVec2(200.0f*dpiScale,0))) {
|
||||
if (ImGui::Button(_("Export"),ImVec2(200.0f*dpiScale,0))) {
|
||||
openFileDialog(GUI_FILE_EXPORT_VGM);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
} else {
|
||||
ImGui::Text("nothing to export");
|
||||
ImGui::Text(_("nothing to export"));
|
||||
if (onWindow) {
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("Cancel",ImVec2(400.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||
if (ImGui::Button(_("Cancel"),ImVec2(400.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::drawExportROM(bool onWindow) {
|
||||
exitDisabledTimer=1;
|
||||
|
||||
const DivROMExportDef* def=e->getROMExportDef(romTarget);
|
||||
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::BeginCombo("##ROMTarget",def==NULL?"<select one>":def->name)) {
|
||||
for (int i=0; i<DIV_ROM_MAX; i++) {
|
||||
const DivROMExportDef* newDef=e->getROMExportDef((DivROMExportOptions)i);
|
||||
if (newDef!=NULL) {
|
||||
if (romExportAvail[i]) {
|
||||
if (ImGui::Selectable(newDef->name)) {
|
||||
romTarget=(DivROMExportOptions)i;
|
||||
romMultiFile=newDef->multiOutput;
|
||||
romConfig=DivConfig();
|
||||
if (newDef->fileExt==NULL) {
|
||||
romFilterName="";
|
||||
romFilterExt="";
|
||||
} else {
|
||||
romFilterName=newDef->fileType;
|
||||
romFilterExt=newDef->fileExt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (def!=NULL) {
|
||||
ImGui::Text("by %s",def->author);
|
||||
|
||||
ImGui::TextWrapped("%s",def->description);
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
bool altered=false;
|
||||
|
||||
switch (romTarget) {
|
||||
case DIV_ROM_TIUNA: {
|
||||
String asmBaseLabel=romConfig.getString("baseLabel","song");
|
||||
int firstBankSize=romConfig.getInt("firstBankSize",3072);
|
||||
int otherBankSize=romConfig.getInt("otherBankSize",4096-48);
|
||||
int sysToExport=romConfig.getInt("sysToExport",-1);
|
||||
|
||||
// TODO; validate label
|
||||
if (ImGui::InputText(_("base song label name"),&asmBaseLabel)) {
|
||||
altered=true;
|
||||
}
|
||||
if (ImGui::InputInt(_("max size in first bank"),&firstBankSize,1,100)) {
|
||||
if (firstBankSize<0) firstBankSize=0;
|
||||
if (firstBankSize>4096) firstBankSize=4096;
|
||||
altered=true;
|
||||
}
|
||||
if (ImGui::InputInt(_("max size in other banks"),&otherBankSize,1,100)) {
|
||||
if (otherBankSize<16) otherBankSize=16;
|
||||
if (otherBankSize>4096) otherBankSize=4096;
|
||||
altered=true;
|
||||
}
|
||||
|
||||
ImGui::Text(_("chip to export:"));
|
||||
for (int i=0; i<e->song.systemLen; i++) {
|
||||
DivSystem sys=e->song.system[i];
|
||||
bool isTIA=(sys==DIV_SYSTEM_TIA);
|
||||
ImGui::BeginDisabled(!isTIA);
|
||||
if (ImGui::RadioButton(fmt::sprintf("%d. %s##_SYSV%d",i+1,getSystemName(e->song.system[i]),i).c_str(),sysToExport==i)) {
|
||||
sysToExport=i;
|
||||
altered=true;
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
if (altered) {
|
||||
romConfig.set("baseLabel",asmBaseLabel);
|
||||
romConfig.set("firstBankSize",firstBankSize);
|
||||
romConfig.set("otherBankSize",otherBankSize);
|
||||
romConfig.set("sysToExport",sysToExport);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DIV_ROM_ABSTRACT:
|
||||
ImGui::TextWrapped("%s",_("select a target from the menu at the top of this dialog."));
|
||||
break;
|
||||
default:
|
||||
ImGui::TextWrapped("%s",_("this export method doesn't offer any options."));
|
||||
break;
|
||||
}
|
||||
/*
|
||||
*/
|
||||
|
||||
if (onWindow) {
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button(_("Cancel"),ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||
ImGui::SameLine();
|
||||
}
|
||||
if (ImGui::Button(_("Export"),ImVec2(200.0f*dpiScale,0))) {
|
||||
openFileDialog(GUI_FILE_EXPORT_ROM);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::drawExportZSM(bool onWindow) {
|
||||
exitDisabledTimer=1;
|
||||
|
||||
ImGui::Text("Commander X16 Zsound Music File");
|
||||
if (ImGui::InputInt("Tick Rate (Hz)",&zsmExportTickRate,1,2)) {
|
||||
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::Checkbox(_("loop"),&zsmExportLoop);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("optimize size",&zsmExportOptimize);
|
||||
ImGui::Checkbox(_("optimize size"),&zsmExportOptimize);
|
||||
if (onWindow) {
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("Cancel",ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||
if (ImGui::Button(_("Cancel"),ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||
ImGui::SameLine();
|
||||
}
|
||||
if (ImGui::Button("Export",ImVec2(200.0f*dpiScale,0))) {
|
||||
if (ImGui::Button(_("Export"),ImVec2(200.0f*dpiScale,0))) {
|
||||
openFileDialog(GUI_FILE_EXPORT_ZSM);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::drawExportAmigaVal(bool onWindow) {
|
||||
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 (onWindow) {
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("Cancel",ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||
ImGui::SameLine();
|
||||
}
|
||||
if (ImGui::Button("Bake Data",ImVec2(200.0f*dpiScale,0))) {
|
||||
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(bool onWindow) {
|
||||
exitDisabledTimer=1;
|
||||
|
||||
ImGui::Text(
|
||||
"this option exports the song to a text file.\n"
|
||||
_("this option exports the song to a text file.\n")
|
||||
);
|
||||
if (onWindow) {
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("Cancel",ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||
if (ImGui::Button(_("Cancel"),ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||
ImGui::SameLine();
|
||||
}
|
||||
if (ImGui::Button("Export",ImVec2(200.0f*dpiScale,0))) {
|
||||
if (ImGui::Button(_("Export"),ImVec2(200.0f*dpiScale,0))) {
|
||||
openFileDialog(GUI_FILE_EXPORT_TEXT);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
|
@ -233,19 +382,19 @@ void FurnaceGUI::drawExportText(bool onWindow) {
|
|||
void FurnaceGUI::drawExportCommand(bool onWindow) {
|
||||
exitDisabledTimer=1;
|
||||
|
||||
ImGui::Text(
|
||||
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 (onWindow) {
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("Cancel",ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||
if (ImGui::Button(_("Cancel"),ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||
ImGui::SameLine();
|
||||
}
|
||||
if (ImGui::Button("Export",ImVec2(200.0f*dpiScale,0))) {
|
||||
if (ImGui::Button(_("Export"),ImVec2(200.0f*dpiScale,0))) {
|
||||
openFileDialog(GUI_FILE_EXPORT_CMDSTREAM);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
|
@ -254,21 +403,21 @@ void FurnaceGUI::drawExportCommand(bool onWindow) {
|
|||
void FurnaceGUI::drawExportDMF(bool onWindow) {
|
||||
exitDisabledTimer=1;
|
||||
|
||||
ImGui::Text(
|
||||
ImGui::Text(_(
|
||||
"export in DefleMask module format.\n"
|
||||
"only do it if you really, really need to, or are downgrading an existing .dmf."
|
||||
);
|
||||
));
|
||||
|
||||
ImGui::Text("format version:");
|
||||
ImGui::RadioButton("1.1.3 and higher",&dmfExportVersion,0);
|
||||
ImGui::RadioButton("1.0/legacy (0.12)",&dmfExportVersion,1);
|
||||
ImGui::Text(_("format version:"));
|
||||
ImGui::RadioButton(_("1.1.3 and higher"),&dmfExportVersion,0);
|
||||
ImGui::RadioButton(_("1.0/legacy (0.12)"),&dmfExportVersion,1);
|
||||
|
||||
if (onWindow) {
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("Cancel",ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||
if (ImGui::Button(_("Cancel"),ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||
ImGui::SameLine();
|
||||
}
|
||||
if (ImGui::Button("Export",ImVec2(200.0f*dpiScale,0))) {
|
||||
if (ImGui::Button(_("Export"),ImVec2(200.0f*dpiScale,0))) {
|
||||
if (dmfExportVersion==1) {
|
||||
openFileDialog(GUI_FILE_SAVE_DMF_LEGACY);
|
||||
} else {
|
||||
|
|
@ -281,43 +430,39 @@ void FurnaceGUI::drawExportDMF(bool onWindow) {
|
|||
void FurnaceGUI::drawExport() {
|
||||
if (settings.exportOptionsLayout==1 || curExportType==GUI_EXPORT_NONE) {
|
||||
if (ImGui::BeginTabBar("ExportTypes")) {
|
||||
if (ImGui::BeginTabItem("Audio")) {
|
||||
if (ImGui::BeginTabItem(_("Audio"))) {
|
||||
drawExportAudio(true);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("VGM")) {
|
||||
if (ImGui::BeginTabItem(_("VGM"))) {
|
||||
drawExportVGM(true);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (romExportExists) {
|
||||
if (ImGui::BeginTabItem(_("ROM"))) {
|
||||
drawExportROM(true);
|
||||
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")) {
|
||||
if (ImGui::BeginTabItem(_("ZSM"))) {
|
||||
drawExportZSM(true);
|
||||
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(true);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
if (ImGui::BeginTabItem("Text")) {
|
||||
if (ImGui::BeginTabItem(_("Text"))) {
|
||||
drawExportText(true);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Command Stream")) {
|
||||
if (ImGui::BeginTabItem(_("Command Stream"))) {
|
||||
drawExportCommand(true);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("DMF")) {
|
||||
if (ImGui::BeginTabItem(_("DMF"))) {
|
||||
drawExportDMF(true);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
|
@ -330,12 +475,12 @@ void FurnaceGUI::drawExport() {
|
|||
case GUI_EXPORT_VGM:
|
||||
drawExportVGM(true);
|
||||
break;
|
||||
case GUI_EXPORT_ROM:
|
||||
drawExportROM(true);
|
||||
break;
|
||||
case GUI_EXPORT_ZSM:
|
||||
drawExportZSM(true);
|
||||
break;
|
||||
case GUI_EXPORT_AMIGA_VAL:
|
||||
drawExportAmigaVal(true);
|
||||
break;
|
||||
case GUI_EXPORT_TEXT:
|
||||
drawExportText(true);
|
||||
break;
|
||||
|
|
@ -346,39 +491,35 @@ void FurnaceGUI::drawExport() {
|
|||
drawExportDMF(true);
|
||||
break;
|
||||
default:
|
||||
ImGui::Text("congratulations! you've unlocked a secret panel.");
|
||||
if (ImGui::Button("Toggle hidden systems")) {
|
||||
ImGui::Text(_("congratulations! you've unlocked a secret panel."));
|
||||
if (ImGui::Button(_("Toggle hidden systems"))) {
|
||||
settings.hiddenSystems=!settings.hiddenSystems;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
if (ImGui::Button("Toggle all instrument types")) {
|
||||
if (ImGui::Button(_("Toggle all instrument types"))) {
|
||||
settings.displayAllInsTypes=!settings.displayAllInsTypes;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
if (ImGui::Button("Set pitch linearity to Partial")) {
|
||||
if (ImGui::Button(_("Set pitch linearity to Partial"))) {
|
||||
e->song.linearPitch=1;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
if (ImGui::Button("Enable multi-threading settings")) {
|
||||
settings.showPool=1;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
if (ImGui::Button("Set fat to max")) {
|
||||
if (ImGui::Button(_("Set fat to max"))) {
|
||||
ImGuiStyle& sty=ImGui::GetStyle();
|
||||
sty.FramePadding=ImVec2(20.0f*dpiScale,20.0f*dpiScale);
|
||||
sty.ItemSpacing=ImVec2(10.0f*dpiScale,10.0f*dpiScale);
|
||||
sty.ItemInnerSpacing=ImVec2(10.0f*dpiScale,10.0f*dpiScale);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
if (ImGui::Button("Set muscle and fat to zero")) {
|
||||
if (ImGui::Button(_("Set muscle and fat to zero"))) {
|
||||
ImGuiStyle& sty=ImGui::GetStyle();
|
||||
sty.FramePadding=ImVec2(0,0);
|
||||
sty.ItemSpacing=ImVec2(0,0);
|
||||
sty.ItemInnerSpacing=ImVec2(0,0);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
if (ImGui::Button("Tell tildearrow this must be a mistake")) {
|
||||
showError("yeah, it's a bug. write a bug report in the GitHub page and tell me how did you get here.");
|
||||
if (ImGui::Button(_("Tell tildearrow this must be a mistake"))) {
|
||||
showError(_("yeah, it's a bug. write a bug report in the GitHub page and tell me how did you get here."));
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -13,12 +13,13 @@
|
|||
|
||||
#ifdef USE_NFD
|
||||
struct NFDState {
|
||||
bool isSave, allowMultiple;
|
||||
unsigned char isSave;
|
||||
bool allowMultiple;
|
||||
String header;
|
||||
std::vector<String> filter;
|
||||
String path;
|
||||
FileDialogSelectCallback clickCallback;
|
||||
NFDState(bool save, String h, std::vector<String> filt, String pa, FileDialogSelectCallback cc, bool multi):
|
||||
NFDState(unsigned char save, String h, std::vector<String> filt, String pa, FileDialogSelectCallback cc, bool multi):
|
||||
isSave(save),
|
||||
allowMultiple(multi),
|
||||
header(h),
|
||||
|
|
@ -36,7 +37,9 @@ void _nfdThread(const NFDState state, std::atomic<bool>* ok, std::vector<String>
|
|||
|
||||
result->clear();
|
||||
|
||||
if (state.isSave) {
|
||||
if (state.isSave==2) {
|
||||
ret=NFD_PickFolder(state.path.c_str(),&out);
|
||||
} else if (state.isSave==1) {
|
||||
ret=NFD_SaveDialog(state.filter,state.path.c_str(),&out,state.clickCallback);
|
||||
} else {
|
||||
if (state.allowMultiple) {
|
||||
|
|
@ -110,9 +113,9 @@ void FurnaceGUIFileDialog::convertFilterList(std::vector<String>& filter) {
|
|||
strncpy(noSysFilter,result.c_str(),4095);
|
||||
}
|
||||
|
||||
bool FurnaceGUIFileDialog::openLoad(String header, std::vector<String> filter, String path, double dpiScale, FileDialogSelectCallback clickCallback, bool allowMultiple) {
|
||||
bool FurnaceGUIFileDialog::openLoad(String header, std::vector<String> filter, String path, double dpiScale, FileDialogSelectCallback clickCallback, bool allowMultiple, String hint) {
|
||||
if (opened) return false;
|
||||
saving=false;
|
||||
dialogType=0;
|
||||
curPath=path;
|
||||
|
||||
// strip excess directory separators
|
||||
|
|
@ -124,12 +127,13 @@ bool FurnaceGUIFileDialog::openLoad(String header, std::vector<String> filter, S
|
|||
|
||||
logD("opening load file dialog with curPath %s",curPath.c_str());
|
||||
if (sysDialog) {
|
||||
curPath+=hint;
|
||||
#ifdef USE_NFD
|
||||
dialogOK=false;
|
||||
#ifdef NFD_NON_THREADED
|
||||
_nfdThread(NFDState(false,header,filter,path,clickCallback,allowMultiple),&dialogOK,&nfdResult,&hasError);
|
||||
_nfdThread(NFDState(0,header,filter,path,clickCallback,allowMultiple),&dialogOK,&nfdResult,&hasError);
|
||||
#else
|
||||
dialogO=new std::thread(_nfdThread,NFDState(false,header,filter,path,clickCallback,allowMultiple),&dialogOK,&nfdResult,&hasError);
|
||||
dialogO=new std::thread(_nfdThread,NFDState(0,header,filter,path,clickCallback,allowMultiple),&dialogOK,&nfdResult,&hasError);
|
||||
#endif
|
||||
#elif defined(ANDROID)
|
||||
hasError=false;
|
||||
|
|
@ -189,13 +193,13 @@ bool FurnaceGUIFileDialog::openLoad(String header, std::vector<String> filter, S
|
|||
ImGuiFileDialog::Instance()->DpiScale=dpiScale;
|
||||
ImGuiFileDialog::Instance()->mobileMode=mobileUI;
|
||||
ImGuiFileDialog::Instance()->homePath=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog",header,noSysFilter,path,allowMultiple?999:1,nullptr,0,clickCallback);
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog",header,filter.empty()?NULL:noSysFilter,path,hint,allowMultiple?999:1,nullptr,0,clickCallback);
|
||||
}
|
||||
opened=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIFileDialog::openSave(String header, std::vector<String> filter, String path, double dpiScale) {
|
||||
bool FurnaceGUIFileDialog::openSave(String header, std::vector<String> filter, String path, double dpiScale, String hint) {
|
||||
if (opened) return false;
|
||||
|
||||
#ifdef ANDROID
|
||||
|
|
@ -204,7 +208,7 @@ bool FurnaceGUIFileDialog::openSave(String header, std::vector<String> filter, S
|
|||
}
|
||||
#endif
|
||||
|
||||
saving=true;
|
||||
dialogType=1;
|
||||
curPath=path;
|
||||
|
||||
// strip excess directory separators
|
||||
|
|
@ -219,9 +223,9 @@ bool FurnaceGUIFileDialog::openSave(String header, std::vector<String> filter, S
|
|||
#ifdef USE_NFD
|
||||
dialogOK=false;
|
||||
#ifdef NFD_NON_THREADED
|
||||
_nfdThread(NFDState(true,header,filter,path,NULL,false),&dialogOK,&nfdResult,&hasError);
|
||||
_nfdThread(NFDState(1,header,filter,path,NULL,false),&dialogOK,&nfdResult,&hasError);
|
||||
#else
|
||||
dialogS=new std::thread(_nfdThread,NFDState(true,header,filter,path,NULL,false),&dialogOK,&nfdResult,&hasError);
|
||||
dialogS=new std::thread(_nfdThread,NFDState(1,header,filter,path,NULL,false),&dialogOK,&nfdResult,&hasError);
|
||||
#endif
|
||||
#elif defined(ANDROID)
|
||||
hasError=false;
|
||||
|
|
@ -275,7 +279,55 @@ bool FurnaceGUIFileDialog::openSave(String header, std::vector<String> filter, S
|
|||
ImGuiFileDialog::Instance()->DpiScale=dpiScale;
|
||||
ImGuiFileDialog::Instance()->mobileMode=mobileUI;
|
||||
ImGuiFileDialog::Instance()->homePath=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog",header,noSysFilter,path,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite);
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog",header,noSysFilter,path,hint,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite);
|
||||
}
|
||||
opened=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIFileDialog::openSelectDir(String header, String path, double dpiScale, String hint) {
|
||||
if (opened) return false;
|
||||
dialogType=2;
|
||||
curPath=path;
|
||||
|
||||
// strip excess directory separators
|
||||
while (!curPath.empty()) {
|
||||
if (curPath[curPath.size()-1]!=DIR_SEPARATOR) break;
|
||||
curPath.erase(curPath.size()-1);
|
||||
}
|
||||
curPath+=DIR_SEPARATOR;
|
||||
|
||||
logD("opening select dir dialog with curPath %s",curPath.c_str());
|
||||
if (sysDialog) {
|
||||
curPath+=hint;
|
||||
#ifdef USE_NFD
|
||||
dialogOK=false;
|
||||
#ifdef NFD_NON_THREADED
|
||||
_nfdThread(NFDState(2,header,std::vector<String>(),path,NULL,false),&dialogOK,&nfdResult,&hasError);
|
||||
#else
|
||||
dialogF=new std::thread(_nfdThread,NFDState(2,header,std::vector<String>(),path,NULL,false),&dialogOK,&nfdResult,&hasError);
|
||||
#endif
|
||||
#elif defined(ANDROID)
|
||||
hasError=true;
|
||||
return false;
|
||||
#else
|
||||
dialogF=new pfd::select_folder(header,path);
|
||||
hasError=!pfd::settings::available();
|
||||
#endif
|
||||
} else {
|
||||
hasError=false;
|
||||
|
||||
#ifdef ANDROID
|
||||
if (!SDL_AndroidRequestPermission("android.permission.READ_EXTERNAL_STORAGE")) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
ImGuiFileDialog::Instance()->singleClickSel=mobileUI;
|
||||
ImGuiFileDialog::Instance()->DpiScale=dpiScale;
|
||||
ImGuiFileDialog::Instance()->mobileMode=mobileUI;
|
||||
ImGuiFileDialog::Instance()->homePath=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog",header,NULL,path,hint,1,nullptr,0);
|
||||
}
|
||||
opened=true;
|
||||
return true;
|
||||
|
|
@ -291,7 +343,17 @@ bool FurnaceGUIFileDialog::accepted() {
|
|||
|
||||
void FurnaceGUIFileDialog::close() {
|
||||
if (sysDialog) {
|
||||
if (saving) {
|
||||
if (dialogType==2) {
|
||||
if (dialogF!=NULL) {
|
||||
#ifdef USE_NFD
|
||||
dialogF->join();
|
||||
#endif
|
||||
#ifndef ANDROID
|
||||
delete dialogF;
|
||||
#endif
|
||||
dialogF=NULL;
|
||||
}
|
||||
} else if (dialogType==1) {
|
||||
if (dialogS!=NULL) {
|
||||
#ifdef USE_NFD
|
||||
dialogS->join();
|
||||
|
|
@ -301,7 +363,7 @@ void FurnaceGUIFileDialog::close() {
|
|||
#endif
|
||||
dialogS=NULL;
|
||||
}
|
||||
} else {
|
||||
} else if (dialogType==0) {
|
||||
if (dialogO!=NULL) {
|
||||
#ifdef USE_NFD
|
||||
dialogO->join();
|
||||
|
|
@ -311,6 +373,8 @@ void FurnaceGUIFileDialog::close() {
|
|||
#endif
|
||||
dialogO=NULL;
|
||||
}
|
||||
} else {
|
||||
logE("what...");
|
||||
}
|
||||
#ifdef USE_NFD
|
||||
dialogOK=false;
|
||||
|
|
@ -342,7 +406,18 @@ bool FurnaceGUIFileDialog::render(const ImVec2& min, const ImVec2& max) {
|
|||
// TODO: detect when file picker is closed
|
||||
return false;
|
||||
#else
|
||||
if (saving) {
|
||||
if (dialogType==2) {
|
||||
if (dialogF!=NULL) {
|
||||
if (dialogF->ready(0)) {
|
||||
fileName.clear();
|
||||
fileName.push_back(dialogF->result());
|
||||
size_t dsPos=fileName[0].rfind(DIR_SEPARATOR);
|
||||
if (dsPos!=String::npos) curPath=fileName[0].substr(0,dsPos);
|
||||
logD("returning %s",fileName[0]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (dialogType==1) {
|
||||
if (dialogS!=NULL) {
|
||||
if (dialogS->ready(0)) {
|
||||
fileName.clear();
|
||||
|
|
@ -353,7 +428,7 @@ bool FurnaceGUIFileDialog::render(const ImVec2& min, const ImVec2& max) {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (dialogType==0) {
|
||||
if (dialogO!=NULL) {
|
||||
if (dialogO->ready(0)) {
|
||||
if (dialogO->result().empty()) {
|
||||
|
|
@ -374,6 +449,8 @@ bool FurnaceGUIFileDialog::render(const ImVec2& min, const ImVec2& max) {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logE("what!");
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
|
|
@ -409,7 +486,7 @@ std::vector<String>& FurnaceGUIFileDialog::getFileName() {
|
|||
return fileName;
|
||||
} else {
|
||||
fileName.clear();
|
||||
if (saving) {
|
||||
if (dialogType!=0) {
|
||||
fileName.push_back(ImGuiFileDialog::Instance()->GetFilePathName());
|
||||
} else {
|
||||
for (auto& i: ImGuiFileDialog::Instance()->GetSelection()) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
namespace pfd {
|
||||
class open_file;
|
||||
class save_file;
|
||||
class select_folder;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -29,7 +30,7 @@ typedef std::function<void(const char*)> FileDialogSelectCallback;
|
|||
class FurnaceGUIFileDialog {
|
||||
bool sysDialog;
|
||||
bool opened;
|
||||
bool saving;
|
||||
unsigned char dialogType;
|
||||
bool hasError;
|
||||
char noSysFilter[4096];
|
||||
String curPath;
|
||||
|
|
@ -37,22 +38,26 @@ class FurnaceGUIFileDialog {
|
|||
#ifdef USE_NFD
|
||||
std::thread* dialogO;
|
||||
std::thread* dialogS;
|
||||
std::thread* dialogF;
|
||||
std::atomic<bool> dialogOK;
|
||||
std::vector<String> nfdResult;
|
||||
#elif defined(ANDROID)
|
||||
JNIEnv* jniEnv;
|
||||
void* dialogO;
|
||||
void* dialogS;
|
||||
void* dialogF;
|
||||
#else
|
||||
pfd::open_file* dialogO;
|
||||
pfd::save_file* dialogS;
|
||||
pfd::select_folder* dialogF;
|
||||
#endif
|
||||
|
||||
void convertFilterList(std::vector<String>& filter);
|
||||
public:
|
||||
bool mobileUI;
|
||||
bool openLoad(String header, std::vector<String> filter, String path, double dpiScale, FileDialogSelectCallback clickCallback=NULL, bool allowMultiple=false);
|
||||
bool openSave(String header, std::vector<String> filter, String path, double dpiScale);
|
||||
bool openLoad(String header, std::vector<String> filter, String path, double dpiScale, FileDialogSelectCallback clickCallback=NULL, bool allowMultiple=false, String hint="");
|
||||
bool openSave(String header, std::vector<String> filter, String path, double dpiScale, String hint="");
|
||||
bool openSelectDir(String header, String path, double dpiScale, String hint="");
|
||||
bool accepted();
|
||||
void close();
|
||||
bool render(const ImVec2& min, const ImVec2& max);
|
||||
|
|
@ -63,7 +68,7 @@ class FurnaceGUIFileDialog {
|
|||
explicit FurnaceGUIFileDialog(bool system):
|
||||
sysDialog(system),
|
||||
opened(false),
|
||||
saving(false),
|
||||
dialogType(0),
|
||||
hasError(false),
|
||||
#ifdef ANDROID
|
||||
jniEnv(NULL),
|
||||
|
|
|
|||
|
|
@ -26,21 +26,21 @@
|
|||
#include "../ta-log.h"
|
||||
|
||||
const char* queryModes[GUI_QUERY_MAX]={
|
||||
"ignore",
|
||||
"equals",
|
||||
"not equal",
|
||||
"between",
|
||||
"not between",
|
||||
"any",
|
||||
"none"
|
||||
_N("ignore"),
|
||||
_N("equals"),
|
||||
_N("not equal"),
|
||||
_N("between"),
|
||||
_N("not between"),
|
||||
_N("any"),
|
||||
_N("none")
|
||||
};
|
||||
|
||||
const char* queryReplaceModes[GUI_QUERY_REPLACE_MAX]={
|
||||
"set",
|
||||
"add",
|
||||
"add (overflow)",
|
||||
"scale %",
|
||||
"clear"
|
||||
_N("set"),
|
||||
_N("add"),
|
||||
_N("add (overflow)"),
|
||||
_N("scale %"),
|
||||
_N("clear")
|
||||
};
|
||||
|
||||
int queryNote(int note, int octave) {
|
||||
|
|
@ -509,7 +509,7 @@ void FurnaceGUI::drawFindReplace() {
|
|||
}
|
||||
if (!findOpen) return;
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(64.0f*dpiScale,32.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||
if (ImGui::Begin("Find/Replace",&findOpen,globalWinFlags)) {
|
||||
if (ImGui::Begin("Find/Replace",&findOpen,globalWinFlags,_("Find/Replace"))) {
|
||||
if (curQuery.empty()) {
|
||||
curQuery.push_back(FurnaceGUIFindQuery());
|
||||
}
|
||||
|
|
@ -517,14 +517,14 @@ void FurnaceGUI::drawFindReplace() {
|
|||
int eraseIndex=-1;
|
||||
char tempID[1024];
|
||||
if (ImGui::BeginTabBar("FindOrReplace")) {
|
||||
if (ImGui::BeginTabItem("Find")) {
|
||||
if (ImGui::BeginTabItem(_("Find"))) {
|
||||
if (queryViewingResults) {
|
||||
if (!curQueryResults.empty()) {
|
||||
ImVec2 avail=ImGui::GetContentRegionAvail();
|
||||
avail.y-=ImGui::GetFrameHeightWithSpacing();
|
||||
if (ImGui::BeginTable("FindResults",4,ImGuiTableFlags_Borders|ImGuiTableFlags_ScrollY,avail)) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,ImGui::CalcTextSize("order").x);
|
||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,ImGui::CalcTextSize("row").x);
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,ImGui::CalcTextSize(_("order")).x);
|
||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,ImGui::CalcTextSize(_("row")).x);
|
||||
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthFixed);
|
||||
|
||||
|
|
@ -532,13 +532,13 @@ void FurnaceGUI::drawFindReplace() {
|
|||
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("order");
|
||||
ImGui::Text(_("order"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("row");
|
||||
ImGui::Text(_("row"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("channel");
|
||||
ImGui::Text(_("channel"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("go");
|
||||
ImGui::Text(_("go"));
|
||||
|
||||
int index=0;
|
||||
for (FurnaceGUIQueryResult& i: curQueryResults) {
|
||||
|
|
@ -582,9 +582,9 @@ void FurnaceGUI::drawFindReplace() {
|
|||
ImGui::EndTable();
|
||||
}
|
||||
} else {
|
||||
ImGui::Text("no matches found!");
|
||||
ImGui::Text(_("no matches found!"));
|
||||
}
|
||||
if (ImGui::Button("Back")) {
|
||||
if (ImGui::Button(_("Back"))) {
|
||||
queryViewingResults=false;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -598,10 +598,10 @@ void FurnaceGUI::drawFindReplace() {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Note");
|
||||
ImGui::Text(_("Note"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::Combo("##NCondition",&i.noteMode,queryModes,GUI_QUERY_MAX);
|
||||
ImGui::Combo("##NCondition",&i.noteMode,LocalizedComboGetter,queryModes,GUI_QUERY_MAX);
|
||||
ImGui::TableNextColumn();
|
||||
if (FIRST_VISIBLE(i.noteMode)) {
|
||||
if ((i.noteMode==GUI_QUERY_RANGE || i.noteMode==GUI_QUERY_RANGE_NOT) && i.note>=120) {
|
||||
|
|
@ -666,10 +666,10 @@ void FurnaceGUI::drawFindReplace() {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Ins");
|
||||
ImGui::Text(_("Ins"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::Combo("##ICondition",&i.insMode,queryModes,GUI_QUERY_MAX);
|
||||
ImGui::Combo("##ICondition",&i.insMode,LocalizedComboGetter,queryModes,GUI_QUERY_MAX);
|
||||
ImGui::TableNextColumn();
|
||||
if (FIRST_VISIBLE(i.insMode)) {
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
|
|
@ -684,10 +684,10 @@ void FurnaceGUI::drawFindReplace() {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Volume");
|
||||
ImGui::Text(_("Volume"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::Combo("##VCondition",&i.volMode,queryModes,GUI_QUERY_MAX);
|
||||
ImGui::Combo("##VCondition",&i.volMode,LocalizedComboGetter,queryModes,GUI_QUERY_MAX);
|
||||
ImGui::TableNextColumn();
|
||||
if (FIRST_VISIBLE(i.volMode)) {
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
|
|
@ -704,10 +704,10 @@ void FurnaceGUI::drawFindReplace() {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Effect");
|
||||
ImGui::Text(_("Effect"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::Combo("##ECondition",&i.effectMode[j],queryModes,GUI_QUERY_MAX);
|
||||
ImGui::Combo("##ECondition",&i.effectMode[j],LocalizedComboGetter,queryModes,GUI_QUERY_MAX);
|
||||
ImGui::TableNextColumn();
|
||||
if (FIRST_VISIBLE(i.effectMode[j])) {
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
|
|
@ -722,10 +722,10 @@ void FurnaceGUI::drawFindReplace() {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Value");
|
||||
ImGui::Text(_("Value"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::Combo("##EVCondition",&i.effectValMode[j],queryModes,GUI_QUERY_MAX);
|
||||
ImGui::Combo("##EVCondition",&i.effectValMode[j],LocalizedComboGetter,queryModes,GUI_QUERY_MAX);
|
||||
ImGui::TableNextColumn();
|
||||
if (FIRST_VISIBLE(i.effectValMode[j])) {
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
|
|
@ -747,18 +747,18 @@ void FurnaceGUI::drawFindReplace() {
|
|||
}
|
||||
popDestColor();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Delete query");
|
||||
ImGui::SetTooltip(_("Delete query"));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (i.effectCount<8) {
|
||||
if (ImGui::Button("Add effect")) {
|
||||
if (ImGui::Button(_("Add effect"))) {
|
||||
i.effectCount++;
|
||||
}
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (i.effectCount>0) {
|
||||
pushDestColor();
|
||||
if (ImGui::Button("Remove effect")) {
|
||||
if (ImGui::Button(_("Remove effect"))) {
|
||||
i.effectCount--;
|
||||
}
|
||||
popDestColor();
|
||||
|
|
@ -783,24 +783,24 @@ void FurnaceGUI::drawFindReplace() {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::Text("Search range:");
|
||||
ImGui::Text(_("Search range:"));
|
||||
|
||||
if (ImGui::RadioButton("Song",curQueryRangeY==0)) {
|
||||
if (ImGui::RadioButton(_("Song"),curQueryRangeY==0)) {
|
||||
curQueryRangeY=0;
|
||||
}
|
||||
if (ImGui::RadioButton("Selection",curQueryRangeY==1)) {
|
||||
if (ImGui::RadioButton(_("Selection"),curQueryRangeY==1)) {
|
||||
curQueryRangeY=1;
|
||||
}
|
||||
if (ImGui::RadioButton("Pattern",curQueryRangeY==2)) {
|
||||
if (ImGui::RadioButton(_("Pattern"),curQueryRangeY==2)) {
|
||||
curQueryRangeY=2;
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox("Confine to channels",&curQueryRangeX);
|
||||
ImGui::Checkbox(_("Confine to channels"),&curQueryRangeX);
|
||||
|
||||
ImGui::BeginDisabled(!curQueryRangeX);
|
||||
snprintf(tempID,1024,"%d: %s",curQueryRangeXMin+1,e->getChannelName(curQueryRangeXMin));
|
||||
if (ImGui::BeginCombo("From",tempID)) {
|
||||
if (ImGui::BeginCombo(_("From"),tempID)) {
|
||||
for (int i=0; i<e->getTotalChannelCount(); i++) {
|
||||
snprintf(tempID,1024,"%d: %s",i+1,e->getChannelName(i));
|
||||
if (ImGui::Selectable(tempID,curQueryRangeXMin==i)) {
|
||||
|
|
@ -811,7 +811,7 @@ void FurnaceGUI::drawFindReplace() {
|
|||
}
|
||||
|
||||
snprintf(tempID,1024,"%d: %s",curQueryRangeXMax+1,e->getChannelName(curQueryRangeXMax));
|
||||
if (ImGui::BeginCombo("To",tempID)) {
|
||||
if (ImGui::BeginCombo(_("To"),tempID)) {
|
||||
for (int i=0; i<e->getTotalChannelCount(); i++) {
|
||||
snprintf(tempID,1024,"%d: %s",i+1,e->getChannelName(i));
|
||||
if (ImGui::Selectable(tempID,curQueryRangeXMax==i)) {
|
||||
|
|
@ -823,37 +823,37 @@ void FurnaceGUI::drawFindReplace() {
|
|||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Match effect position:");
|
||||
ImGui::Text(_("Match effect position:"));
|
||||
|
||||
if (ImGui::RadioButton("No",curQueryEffectPos==0)) {
|
||||
if (ImGui::RadioButton(_("No"),curQueryEffectPos==0)) {
|
||||
curQueryEffectPos=0;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("match effects regardless of position.");
|
||||
ImGui::SetTooltip(_("match effects regardless of position."));
|
||||
}
|
||||
if (ImGui::RadioButton("Lax",curQueryEffectPos==1)) {
|
||||
if (ImGui::RadioButton(_("Lax"),curQueryEffectPos==1)) {
|
||||
curQueryEffectPos=1;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("match effects only if they appear in-order.");
|
||||
ImGui::SetTooltip(_("match effects only if they appear in-order."));
|
||||
}
|
||||
if (ImGui::RadioButton("Strict",curQueryEffectPos==2)) {
|
||||
if (ImGui::RadioButton(_("Strict"),curQueryEffectPos==2)) {
|
||||
curQueryEffectPos=2;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("match effects only if they appear exactly as specified.");
|
||||
ImGui::SetTooltip(_("match effects only if they appear exactly as specified."));
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if (ImGui::Button("Find")) {
|
||||
if (ImGui::Button(_("Find"))) {
|
||||
doFind();
|
||||
}
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Replace")) {
|
||||
if (ImGui::BeginTabItem(_("Replace"))) {
|
||||
if (ImGui::BeginTable("QueryReplace",3,ImGuiTableFlags_BordersOuter)) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.5);
|
||||
|
|
@ -861,11 +861,11 @@ void FurnaceGUI::drawFindReplace() {
|
|||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox("Note",&queryReplaceNoteDo);
|
||||
ImGui::Checkbox(_("Note"),&queryReplaceNoteDo);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::BeginDisabled(!queryReplaceNoteDo);
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::Combo("##NRMode",&queryReplaceNoteMode,queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
||||
ImGui::Combo("##NRMode",&queryReplaceNoteMode,LocalizedComboGetter,queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (queryReplaceNoteMode==GUI_QUERY_REPLACE_SET) {
|
||||
|
|
@ -905,17 +905,17 @@ void FurnaceGUI::drawFindReplace() {
|
|||
if (queryReplaceNote>180) queryReplaceNote=180;
|
||||
}
|
||||
} else if (queryReplaceNoteMode==GUI_QUERY_REPLACE_SCALE) {
|
||||
ImGui::Text("INVALID");
|
||||
ImGui::Text(_("INVALID"));
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox("Ins",&queryReplaceInsDo);
|
||||
ImGui::Checkbox(_("Ins"),&queryReplaceInsDo);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::BeginDisabled(!queryReplaceInsDo);
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::Combo("##IRMode",&queryReplaceInsMode,queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
||||
ImGui::Combo("##IRMode",&queryReplaceInsMode,LocalizedComboGetter,queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (queryReplaceInsMode==GUI_QUERY_REPLACE_SET) {
|
||||
|
|
@ -940,11 +940,11 @@ void FurnaceGUI::drawFindReplace() {
|
|||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox("Volume",&queryReplaceVolDo);
|
||||
ImGui::Checkbox(_("Volume"),&queryReplaceVolDo);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::BeginDisabled(!queryReplaceVolDo);
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::Combo("##VRMode",&queryReplaceVolMode,queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
||||
ImGui::Combo("##VRMode",&queryReplaceVolMode,LocalizedComboGetter,queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (queryReplaceVolMode==GUI_QUERY_REPLACE_SET) {
|
||||
|
|
@ -971,11 +971,11 @@ void FurnaceGUI::drawFindReplace() {
|
|||
ImGui::PushID(0x100+i);
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox("Effect",&queryReplaceEffectDo[i]);
|
||||
ImGui::Checkbox(_("Effect"),&queryReplaceEffectDo[i]);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::BeginDisabled(!queryReplaceEffectDo[i]);
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::Combo("##ERMode",&queryReplaceEffectMode[i],queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
||||
ImGui::Combo("##ERMode",&queryReplaceEffectMode[i],LocalizedComboGetter,queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (queryReplaceEffectMode[i]==GUI_QUERY_REPLACE_SET) {
|
||||
|
|
@ -1000,11 +1000,11 @@ void FurnaceGUI::drawFindReplace() {
|
|||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox("Value",&queryReplaceEffectValDo[i]);
|
||||
ImGui::Checkbox(_("Value"),&queryReplaceEffectValDo[i]);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::BeginDisabled(!queryReplaceEffectValDo[i]);
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::Combo("##ERModeV",&queryReplaceEffectValMode[i],queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
||||
ImGui::Combo("##ERModeV",&queryReplaceEffectValMode[i],LocalizedComboGetter,queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (queryReplaceEffectValMode[i]==GUI_QUERY_REPLACE_SET) {
|
||||
|
|
@ -1034,14 +1034,14 @@ void FurnaceGUI::drawFindReplace() {
|
|||
ImGui::TableNextColumn();
|
||||
ImGui::TableNextColumn();
|
||||
if (queryReplaceEffectCount<8) {
|
||||
if (ImGui::Button("Add effect")) {
|
||||
if (ImGui::Button(_("Add effect"))) {
|
||||
queryReplaceEffectCount++;
|
||||
}
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (queryReplaceEffectCount>0) {
|
||||
pushDestColor();
|
||||
if (ImGui::Button("Remove effect")) {
|
||||
if (ImGui::Button(_("Remove effect"))) {
|
||||
queryReplaceEffectCount--;
|
||||
}
|
||||
popDestColor();
|
||||
|
|
@ -1049,20 +1049,20 @@ void FurnaceGUI::drawFindReplace() {
|
|||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::Text("Effect replace mode:");
|
||||
if (ImGui::RadioButton("Replace matches only",queryReplaceEffectPos==1)) {
|
||||
ImGui::Text(_("Effect replace mode:"));
|
||||
if (ImGui::RadioButton(_("Replace matches only"),queryReplaceEffectPos==1)) {
|
||||
queryReplaceEffectPos=1;
|
||||
}
|
||||
if (ImGui::RadioButton("Replace matches, then free spaces",queryReplaceEffectPos==2)) {
|
||||
if (ImGui::RadioButton(_("Replace matches, then free spaces"),queryReplaceEffectPos==2)) {
|
||||
queryReplaceEffectPos=2;
|
||||
}
|
||||
if (ImGui::RadioButton("Clear effects",queryReplaceEffectPos==0)) {
|
||||
if (ImGui::RadioButton(_("Clear effects"),queryReplaceEffectPos==0)) {
|
||||
queryReplaceEffectPos=0;
|
||||
}
|
||||
if (ImGui::RadioButton("Insert in free spaces",queryReplaceEffectPos==3)) {
|
||||
if (ImGui::RadioButton(_("Insert in free spaces"),queryReplaceEffectPos==3)) {
|
||||
queryReplaceEffectPos=3;
|
||||
}
|
||||
if (ImGui::Button("Replace##QueryReplace")) {
|
||||
if (ImGui::Button(_("Replace##QueryReplace"))) {
|
||||
doReplace();
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
|
|
|
|||
5239
src/gui/font_exo.cpp
5239
src/gui/font_exo.cpp
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
11856
src/gui/font_icon.cpp
11856
src/gui/font_icon.cpp
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
128045
src/gui/font_plexSansJP.cpp
Normal file
128045
src/gui/font_plexSansJP.cpp
Normal file
File diff suppressed because it is too large
Load diff
51400
src/gui/font_plexSansKR.cpp
Normal file
51400
src/gui/font_plexSansKR.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,209 +1,501 @@
|
|||
// papers/proggy-license.txt
|
||||
// File: 'ProggyClean.ttf' (41208 bytes)
|
||||
// Exported using binary_to_compressed_c.cpp
|
||||
#include "fonts.h"
|
||||
|
||||
const unsigned int font_proggyClean_compressed_size = 9583;
|
||||
const unsigned int font_proggyClean_compressed_data[9584/4] =
|
||||
{
|
||||
0x0000bc57, 0x00000000, 0xf8a00000, 0x00000400, 0x00010037, 0x000c0000, 0x00030080, 0x2f534f40, 0x74eb8832, 0x01000090, 0x2c158248, 0x616d634e,
|
||||
0x23120270, 0x03000075, 0x241382a0, 0x74766352, 0x82178220, 0xfc042102, 0x02380482, 0x66796c67, 0x5689af12, 0x04070000, 0x80920000, 0x64616568,
|
||||
0xd36691d7, 0xcc201b82, 0x36210382, 0x27108268, 0xc3014208, 0x04010000, 0x243b0f82, 0x78746d68, 0x807e008a, 0x98010000, 0x06020000, 0x61636f6c,
|
||||
0xd8b0738c, 0x82050000, 0x0402291e, 0x7078616d, 0xda00ae01, 0x28201f82, 0x202c1082, 0x656d616e, 0x96bb5925, 0x84990000, 0x9e2c1382, 0x74736f70,
|
||||
0xef83aca6, 0x249b0000, 0xd22c3382, 0x70657270, 0x12010269, 0xf4040000, 0x08202f82, 0x012ecb84, 0x553c0000, 0x0f5fd5e9, 0x0300f53c, 0x00830008,
|
||||
0x7767b722, 0x002b3f82, 0xa692bd00, 0xfe0000d7, 0x83800380, 0x21f1826f, 0x00850002, 0x41820120, 0x40fec026, 0x80030000, 0x05821083, 0x07830120,
|
||||
0x0221038a, 0x24118200, 0x90000101, 0x82798200, 0x00022617, 0x00400008, 0x2009820a, 0x82098276, 0x82002006, 0x9001213b, 0x0223c883, 0x828a02bc,
|
||||
0x858f2010, 0xc5012507, 0x00023200, 0x04210083, 0x91058309, 0x6c412b03, 0x40007374, 0xac200000, 0x00830008, 0x01000523, 0x834d8380, 0x80032103,
|
||||
0x012101bf, 0x23b88280, 0x00800000, 0x0b830382, 0x07820120, 0x83800021, 0x88012001, 0x84002009, 0x2005870f, 0x870d8301, 0x2023901b, 0x83199501,
|
||||
0x82002015, 0x84802000, 0x84238267, 0x88002027, 0x8561882d, 0x21058211, 0x13880000, 0x01800022, 0x05850d85, 0x0f828020, 0x03208384, 0x03200582,
|
||||
0x47901b84, 0x1b850020, 0x1f821d82, 0x3f831d88, 0x3f410383, 0x84058405, 0x210982cd, 0x09830000, 0x03207789, 0xf38a1384, 0x01203782, 0x13872384,
|
||||
0x0b88c983, 0x0d898f84, 0x00202982, 0x23900383, 0x87008021, 0x83df8301, 0x86118d03, 0x863f880d, 0x8f35880f, 0x2160820f, 0x04830300, 0x1c220382,
|
||||
0x05820100, 0x4c000022, 0x09831182, 0x04001c24, 0x11823000, 0x0800082e, 0x00000200, 0xff007f00, 0xffffac20, 0x00220982, 0x09848100, 0xdf216682,
|
||||
0x843586d5, 0x06012116, 0x04400684, 0xa58120d7, 0x00b127d8, 0x01b88d01, 0x2d8685ff, 0xc100c621, 0xf4be0801, 0x9e011c01, 0x88021402, 0x1403fc02,
|
||||
0x9c035803, 0x1404de03, 0x50043204, 0xa2046204, 0x66051605, 0x1206bc05, 0xd6067406, 0x7e073807, 0x4e08ec07, 0x96086c08, 0x1009d008, 0x88094a09,
|
||||
0x800a160a, 0x560b040b, 0x2e0cc80b, 0xea0c820c, 0xa40d5e0d, 0x500eea0d, 0x280f960e, 0x1210b00f, 0xe0107410, 0xb6115211, 0x6e120412, 0x4c13c412,
|
||||
0xf613ac13, 0xae145814, 0x4015ea14, 0xa6158015, 0x1216b815, 0xc6167e16, 0x8e173417, 0x5618e017, 0xee18ba18, 0x96193619, 0x481ad419, 0xf01a9c1a,
|
||||
0xc81b5c1b, 0x4c1c041c, 0xea1c961c, 0x921d2a1d, 0x401ed21d, 0xe01e8e1e, 0x761f241f, 0xa61fa61f, 0x01821020, 0x8a202e34, 0xc820b220, 0x74211421,
|
||||
0xee219821, 0x86226222, 0x01820c23, 0x83238021, 0x23983c01, 0x24d823b0, 0x244a2400, 0x24902468, 0x250625ae, 0x25822560, 0x26f825f8, 0x82aa2658,
|
||||
0xd8be0801, 0x9a274027, 0x68280a28, 0x0e29a828, 0xb8292029, 0x362af829, 0x602a602a, 0x2a2b022b, 0xac2b5e2b, 0x202ce62b, 0x9a2c342c, 0x5c2d282d,
|
||||
0xaa2d782d, 0x262ee82d, 0x262fa62e, 0xf42fb62f, 0xc8305e30, 0xb4313e31, 0x9e321e32, 0x82331e33, 0x5c34ee33, 0x3a35ce34, 0xd4358635, 0x72362636,
|
||||
0x7637e636, 0x3a38d837, 0x1239a638, 0xae397439, 0x9a3a2e3a, 0x7c3b063b, 0x3a3ce83b, 0x223d963c, 0xec3d863d, 0xc63e563e, 0x9a3f2a3f, 0x6a401240,
|
||||
0x3641d040, 0x0842a241, 0x7a424042, 0xf042b842, 0xcc436243, 0x8a442a44, 0x5845ee44, 0xe245b645, 0xb4465446, 0x7a471447, 0x5448da47, 0x4049c648,
|
||||
0x15462400, 0x034d0808, 0x0b000700, 0x13000f00, 0x1b001700, 0x23001f00, 0x2b002700, 0x33002f00, 0x3b003700, 0x43003f00, 0x4b004700, 0x53004f00,
|
||||
0x5b005700, 0x63005f00, 0x6b006700, 0x73006f00, 0x7b007700, 0x83007f00, 0x8b008700, 0x00008f00, 0x15333511, 0x20039631, 0x20178205, 0xd3038221,
|
||||
0x20739707, 0x25008580, 0x028080fc, 0x05be8080, 0x04204a85, 0x05ce0685, 0x0107002a, 0x02000080, 0x00000400, 0x250d8b41, 0x33350100, 0x03920715,
|
||||
0x13820320, 0x858d0120, 0x0e8d0320, 0xff260d83, 0x00808000, 0x54820106, 0x04800223, 0x845b8c80, 0x41332059, 0x078b068f, 0x82000121, 0x82fe2039,
|
||||
0x84802003, 0x83042004, 0x23598a0e, 0x00180000, 0x03210082, 0x42ab9080, 0x73942137, 0x2013bb41, 0x8f978205, 0x2027a39b, 0x20b68801, 0x84b286fd,
|
||||
0x91c88407, 0x41032011, 0x11a51130, 0x15000027, 0x80ff8000, 0x11af4103, 0x841b0341, 0x8bd983fd, 0x9be99bc9, 0x8343831b, 0x21f1821f, 0xb58300ff,
|
||||
0x0f84e889, 0xf78a0484, 0x8000ff22, 0x0020eeb3, 0x14200082, 0x2130ef41, 0xeb431300, 0x4133200a, 0xd7410ecb, 0x9a07200b, 0x2027871b, 0x21238221,
|
||||
0xe7828080, 0xe784fd20, 0xe8848020, 0xfe808022, 0x08880d85, 0xba41fd20, 0x82248205, 0x85eab02a, 0x008022e7, 0x2cd74200, 0x44010021, 0xd34406eb,
|
||||
0x44312013, 0xcf8b0eef, 0x0d422f8b, 0x82332007, 0x0001212f, 0x8023cf82, 0x83000180, 0x820583de, 0x830682d4, 0x820020d4, 0x82dc850a, 0x20e282e9,
|
||||
0xb2ff85fe, 0x010327e9, 0x02000380, 0x0f440400, 0x0c634407, 0x68825982, 0x85048021, 0x260a825d, 0x010b0000, 0x4400ff00, 0x2746103f, 0x08d74209,
|
||||
0x4d440720, 0x0eaf4406, 0xc3441d20, 0x23078406, 0xff800002, 0x04845b83, 0x8d05b241, 0x1781436f, 0x6b8c87a5, 0x1521878e, 0x06474505, 0x01210783,
|
||||
0x84688c00, 0x8904828e, 0x441e8cf7, 0x0b270cff, 0x80008000, 0x45030003, 0xfb430fab, 0x080f4107, 0x410bf942, 0xd34307e5, 0x070d4207, 0x80800123,
|
||||
0x205d85fe, 0x849183fe, 0x20128404, 0x82809702, 0x00002217, 0x41839a09, 0x6b4408cf, 0x0733440f, 0x3b460720, 0x82798707, 0x97802052, 0x0000296f,
|
||||
0xff800004, 0x01800100, 0x0021ef89, 0x0a914625, 0x410a4d41, 0x00250ed4, 0x00050000, 0x056d4280, 0x210a7b46, 0x21481300, 0x46ed8512, 0x00210bd1,
|
||||
0x89718202, 0x21738877, 0x2b850001, 0x00220582, 0x87450a00, 0x0ddb4606, 0x41079b42, 0x9d420c09, 0x0b09420b, 0x8d820720, 0x9742fc84, 0x42098909,
|
||||
0x00241e0f, 0x00800014, 0x0b47da82, 0x0833442a, 0x49078d41, 0x2f450f13, 0x42278f17, 0x01200751, 0x22063742, 0x44808001, 0x20450519, 0x88068906,
|
||||
0x83fe2019, 0x4203202a, 0x1a941a58, 0x00820020, 0xe7a40e20, 0x420ce146, 0x854307e9, 0x0fcb4713, 0xff20a182, 0xfe209b82, 0x0c867f8b, 0x0021aea4,
|
||||
0x219fa40f, 0x7d41003b, 0x07194214, 0xbf440520, 0x071d4206, 0x6941a590, 0x80802309, 0x028900ff, 0xa9a4b685, 0xc5808021, 0x449b82ab, 0x152007eb,
|
||||
0x42134d46, 0x61440a15, 0x051e4208, 0x222b0442, 0x47001100, 0xfd412913, 0x17194714, 0x410f5b41, 0x02220773, 0x09428080, 0x21a98208, 0xd4420001,
|
||||
0x481c840d, 0x00232bc9, 0x42120000, 0xe74c261b, 0x149d4405, 0x07209d87, 0x410db944, 0x14421c81, 0x42fd2005, 0x80410bd2, 0x203d8531, 0x06874100,
|
||||
0x48256f4a, 0xcb420c95, 0x13934113, 0x44075d44, 0x044c0855, 0x00ff2105, 0xfe228185, 0x45448000, 0x22c5b508, 0x410c0000, 0x7b412087, 0x1bb74514,
|
||||
0x32429c85, 0x0a574805, 0x21208943, 0x8ba01300, 0x440dfb4e, 0x77431437, 0x245b4113, 0x200fb145, 0x41108ffe, 0x80203562, 0x00200082, 0x46362b42,
|
||||
0x1742178d, 0x4527830f, 0x0f830b2f, 0x4a138146, 0x802409a1, 0xfe8000ff, 0x94419982, 0x09294320, 0x04000022, 0x49050f4f, 0xcb470a63, 0x48032008,
|
||||
0x2b48067b, 0x85022008, 0x82638338, 0x00002209, 0x05af4806, 0x900e9f49, 0x84c5873f, 0x214285bd, 0x064900ff, 0x0c894607, 0x00000023, 0x4903820a,
|
||||
0x714319f3, 0x0749410c, 0x8a07a145, 0x02152507, 0xfe808000, 0x74490386, 0x8080211b, 0x0c276f82, 0x00018000, 0x48028003, 0x2b2315db, 0x43002f00,
|
||||
0x6f82142f, 0x44011521, 0x93510da7, 0x20e68508, 0x06494d80, 0x8e838020, 0x06821286, 0x124bff20, 0x25f3830c, 0x03800080, 0xe74a0380, 0x207b8715,
|
||||
0x876b861d, 0x4a152007, 0x07870775, 0xf6876086, 0x8417674a, 0x0a0021f2, 0x431c9743, 0x8d421485, 0x200b830b, 0x06474d03, 0x71828020, 0x04510120,
|
||||
0x42da8606, 0x1f831882, 0x001a0022, 0xff4d0082, 0x0b0f532c, 0x0d449b94, 0x4e312007, 0x074f12e7, 0x0bf3490b, 0xbb412120, 0x413f820a, 0xef490857,
|
||||
0x80002313, 0xe2830001, 0x6441fc20, 0x8b802006, 0x00012108, 0xfd201582, 0x492c9b48, 0x802014ff, 0x51084347, 0x0f4327f3, 0x17bf4a14, 0x201b7944,
|
||||
0x06964201, 0x134ffe20, 0x20d6830b, 0x25d78280, 0xfd800002, 0x05888000, 0x9318dc41, 0x21d282d4, 0xdb481800, 0x0dff542a, 0x45107743, 0xe14813f5,
|
||||
0x0f034113, 0x83135d45, 0x47b28437, 0xe4510e73, 0x21f58e06, 0x2b8400fd, 0x1041fcac, 0x08db4b0b, 0x421fdb41, 0xdf4b18df, 0x011d210a, 0x420af350,
|
||||
0x6e8308af, 0xac85cb86, 0x1e461082, 0x82b7a407, 0x411420a3, 0xa34130ab, 0x178f4124, 0x41139741, 0x86410d93, 0x82118511, 0x057243d8, 0x8941d9a4,
|
||||
0x3093480c, 0x4a13474f, 0xfb5016a9, 0x07ad4108, 0x4a0f9d42, 0xfe200fad, 0x4708aa41, 0x83482dba, 0x288f4d06, 0xb398c3bb, 0x44267b41, 0xb34439d7,
|
||||
0x0755410f, 0x200ebb45, 0x0f5f4215, 0x20191343, 0x06df5301, 0xf04c0220, 0x2ba64d07, 0x82050841, 0x430020ce, 0xa78f3627, 0x5213ff42, 0x2f970bc1,
|
||||
0x4305ab55, 0xa084111b, 0x450bac45, 0x5f4238b8, 0x010c2106, 0x0220ed82, 0x441bb344, 0x875010af, 0x0737480f, 0x490c5747, 0x0c840c03, 0x4c204b42,
|
||||
0x8ba905d7, 0x8b948793, 0x510c0c51, 0xfb4b24b9, 0x1b174107, 0x5709d74c, 0xd1410ca5, 0x079d480f, 0x201ff541, 0x06804780, 0x7d520120, 0x80002205,
|
||||
0x20a983fe, 0x47bb83fe, 0x1b8409b4, 0x81580220, 0x4e00202c, 0x4f41282f, 0x0eab4f17, 0x57471520, 0x0e0f4808, 0x8221e041, 0x3e1b4a8b, 0x4407175d,
|
||||
0x1b4b071f, 0x4a0f8b07, 0x174a0703, 0x0ba5411b, 0x430fb141, 0x0120057b, 0xfc20dd82, 0x4a056047, 0xf4850c0c, 0x01221982, 0x02828000, 0x1a5d088b,
|
||||
0x20094108, 0x8c0e3941, 0x4900200e, 0x7744434f, 0x200b870b, 0x0e4b5a33, 0x2b41f78b, 0x8b138307, 0x0b9f450b, 0x2406f741, 0xfd808001, 0x09475a00,
|
||||
0x84000121, 0x5980200e, 0x85450e5d, 0x832c8206, 0x4106831e, 0x00213814, 0x28b34810, 0x410c2f4b, 0x5f4a13d7, 0x0b2b4113, 0x6e43a883, 0x11174b05,
|
||||
0x4b066a45, 0xcc470541, 0x5000202b, 0xcb472f4b, 0x44b59f0f, 0xc5430b5b, 0x0d654907, 0x21065544, 0xd6828080, 0xfe201982, 0x8230ec4a, 0x120025c2,
|
||||
0x80ff8000, 0x4128d74d, 0x3320408b, 0x410a9f50, 0xdb822793, 0x822bd454, 0x61134b2e, 0x410b214a, 0xad4117c9, 0x0001211f, 0x4206854f, 0x4b430596,
|
||||
0x06bb5530, 0x2025cf46, 0x0ddd5747, 0x500ea349, 0x0f840fa7, 0x5213c153, 0x634e08d1, 0x0bbe4809, 0x59316e4d, 0x5b50053f, 0x203f6323, 0x5117eb46,
|
||||
0x94450a63, 0x246e410a, 0x63410020, 0x0bdb5f2f, 0x4233ab44, 0x39480757, 0x112d4a07, 0x7241118f, 0x000e2132, 0x9f286f41, 0x0f8762c3, 0x33350723,
|
||||
0x094e6415, 0x2010925f, 0x067252fe, 0xd0438020, 0x63a68225, 0x11203a4f, 0x480e6360, 0x5748131f, 0x079b521f, 0x200e2f43, 0x864b8315, 0x113348e7,
|
||||
0x85084e48, 0x06855008, 0x5880fd21, 0x7c420925, 0x0c414824, 0x37470c86, 0x1b8b422b, 0x5b0a8755, 0x23410c21, 0x0b83420b, 0x5a082047, 0xf482067f,
|
||||
0xa80b4c47, 0x0c0021cf, 0x20207b42, 0x0fb74100, 0x420b8744, 0xeb43076f, 0x0f6f420b, 0x4261fe20, 0x439aa00c, 0x215034e3, 0x0ff9570f, 0x4b1f2d5d,
|
||||
0x2d5d0c6f, 0x09634d0b, 0x1f51b8a0, 0x620f200c, 0xaf681e87, 0x24f94d07, 0x4e0f4945, 0xfe200c05, 0x22139742, 0x57048080, 0x23950c20, 0x97601585,
|
||||
0x4813201f, 0xad620523, 0x200f8f0f, 0x9e638f15, 0x00002181, 0x41342341, 0x0f930f0b, 0x210b4b62, 0x978f0001, 0xfe200f84, 0x8425c863, 0x2704822b,
|
||||
0x80000a00, 0x00038001, 0x610e9768, 0x834514bb, 0x0bc3430f, 0x2107e357, 0x80848080, 0x4400fe21, 0x2e410983, 0x00002a1a, 0x00000700, 0x800380ff,
|
||||
0x0fdf5800, 0x59150021, 0xd142163d, 0x0c02410c, 0x01020025, 0x65800300, 0x00240853, 0x1d333501, 0x15220382, 0x35420001, 0x44002008, 0x376406d7,
|
||||
0x096f6b19, 0x480bc142, 0x8f4908a7, 0x211f8b1f, 0x9e830001, 0x0584fe20, 0x4180fd21, 0x11850910, 0x8d198259, 0x000021d4, 0x5a08275d, 0x275d1983,
|
||||
0x06d9420e, 0x9f08b36a, 0x0f7d47b5, 0x8d8a2f8b, 0x4c0e0b57, 0xe7410e17, 0x42d18c1a, 0xb351087a, 0x1ac36505, 0x4b4a2f20, 0x0b9f450d, 0x430beb53,
|
||||
0xa7881015, 0xa5826a83, 0x80200f82, 0x86185a65, 0x4100208e, 0x176c3367, 0x0fe7650b, 0x4a17ad4b, 0x0f4217ed, 0x112e4206, 0x41113a42, 0xf7423169,
|
||||
0x0cb34737, 0x560f8b46, 0xa75407e5, 0x5f01200f, 0x31590c48, 0x80802106, 0x42268841, 0x0020091e, 0x4207ef64, 0x69461df7, 0x138d4114, 0x820f5145,
|
||||
0x53802090, 0xff200529, 0xb944b183, 0x417e8505, 0x00202561, 0x15210082, 0x42378200, 0x9b431cc3, 0x004f220d, 0x0dd54253, 0x4213f149, 0x7d41133b,
|
||||
0x42c9870b, 0x802010f9, 0x420b2c42, 0x8f441138, 0x267c4408, 0x600cb743, 0x8f4109d3, 0x05ab701d, 0x83440020, 0x3521223f, 0x0b794733, 0xfb62fe20,
|
||||
0x4afd2010, 0xaf410ae7, 0x25ce8525, 0x01080000, 0x7b6b0000, 0x0973710b, 0x82010021, 0x49038375, 0x33420767, 0x052c4212, 0x58464b85, 0x41fe2005,
|
||||
0x50440c27, 0x000c2209, 0x1cb36b80, 0x9b06df44, 0x0f93566f, 0x52830220, 0xfe216e8d, 0x200f8200, 0x0fb86704, 0xb057238d, 0x050b5305, 0x7217eb47,
|
||||
0xbd410b6b, 0x0f214610, 0x871f9956, 0x1e91567e, 0x2029b741, 0x20008200, 0x18b7410a, 0x27002322, 0x41095543, 0x0f8f0fb3, 0x41000121, 0x889d111c,
|
||||
0x14207b82, 0x00200382, 0x73188761, 0x475013a7, 0x6e33200c, 0x234e0ea3, 0x9b138313, 0x08e54d17, 0x9711094e, 0x2ee74311, 0x4908875e, 0xd75d1f1f,
|
||||
0x19ab5238, 0xa2084d48, 0x63a7a9b3, 0x55450b83, 0x0fd74213, 0x440d814c, 0x4f481673, 0x05714323, 0x13000022, 0x412e1f46, 0xdf493459, 0x21c7550f,
|
||||
0x8408215f, 0x201d49cb, 0xb1103043, 0x0f0d65d7, 0x452b8d41, 0x594b0f8d, 0x0b004605, 0xb215eb46, 0x000a24d7, 0x47000080, 0x002118cf, 0x06436413,
|
||||
0x420bd750, 0x2b500743, 0x076a470c, 0x4105c050, 0xd942053f, 0x0d00211a, 0x5f44779c, 0x0ce94805, 0x51558186, 0x14a54c0b, 0x49082b41, 0x0a4b0888,
|
||||
0x8080261f, 0x0d000000, 0x20048201, 0x1deb6a03, 0x420cb372, 0x07201783, 0x4306854d, 0x8b830c59, 0x59093c74, 0x0020250f, 0x67070f4a, 0x2341160b,
|
||||
0x00372105, 0x431c515d, 0x554e17ef, 0x0e5d6b05, 0x41115442, 0xb74a1ac1, 0x2243420a, 0x5b4f878f, 0x7507200f, 0x384b086f, 0x09d45409, 0x0020869a,
|
||||
0x12200082, 0xab460382, 0x10075329, 0x54138346, 0xaf540fbf, 0x1ea75413, 0x9a0c9e54, 0x0f6b44c1, 0x41000021, 0x47412a4f, 0x07374907, 0x5310bf76,
|
||||
0xff2009b4, 0x9a09a64c, 0x8200208d, 0x34c34500, 0x970fe141, 0x1fd74b0f, 0x440a3850, 0x206411f0, 0x27934609, 0x470c5d41, 0x555c2947, 0x1787540f,
|
||||
0x6e0f234e, 0x7d540a1b, 0x1d736b08, 0x0026a088, 0x80000e00, 0x9b5200ff, 0x08ef4318, 0x450bff77, 0x1d4d0b83, 0x081f7006, 0xcb691b86, 0x4b022008,
|
||||
0xc34b0b33, 0x1d0d4a0c, 0x8025a188, 0x0b000000, 0x52a38201, 0xbf7d0873, 0x0c234511, 0x8f0f894a, 0x4101200f, 0x0c880c9d, 0x2b418ea1, 0x06c74128,
|
||||
0x66181341, 0x7b4c0bb9, 0x0c06630b, 0xfe200c87, 0x9ba10882, 0x27091765, 0x01000008, 0x02800380, 0x48113f4e, 0x29430cf5, 0x09a75a0b, 0x31618020,
|
||||
0x6d802009, 0x61840e33, 0x8208bf51, 0x0c637d61, 0x7f092379, 0x4f470f4b, 0x1797510c, 0x46076157, 0xf5500fdf, 0x0f616910, 0x1171fe20, 0x82802006,
|
||||
0x08696908, 0x41127a4c, 0x3f4a15f3, 0x01042607, 0x0200ff00, 0x1cf77700, 0xff204185, 0x00235b8d, 0x43100000, 0x3b22243f, 0x3b4d3f00, 0x0b937709,
|
||||
0xad42f18f, 0x0b1f420f, 0x51084b43, 0x8020104a, 0xb557ff83, 0x052b7f2a, 0x0280ff22, 0x250beb78, 0x00170013, 0xbf6d2500, 0x07db760e, 0x410e2b7f,
|
||||
0x00230e4f, 0x49030000, 0x0582055b, 0x07000326, 0x00000b00, 0x580bcd46, 0x00200cdd, 0x57078749, 0x8749160f, 0x0f994f0a, 0x41134761, 0x01200b31,
|
||||
0xeb796883, 0x0b41500b, 0x0e90b38e, 0x202e7b51, 0x05d95801, 0x41080570, 0x1d530fc9, 0x0b937a0f, 0xaf8eb387, 0xf743b98f, 0x07c74227, 0x80000523,
|
||||
0x0fcb4503, 0x430ca37b, 0x7782077f, 0x8d0a9947, 0x08af4666, 0xeb798020, 0x6459881e, 0xc3740bbf, 0x0feb6f0b, 0x20072748, 0x052b6102, 0x435e0584,
|
||||
0x7d088308, 0x03200afd, 0x92109e41, 0x28aa8210, 0x80001500, 0x80030000, 0x0fdb5805, 0x209f4018, 0xa7418d87, 0x0aa3440f, 0x20314961, 0x073a52ff,
|
||||
0x6108505d, 0x43181051, 0x00223457, 0xe7820500, 0x50028021, 0x81410d33, 0x063d7108, 0xdb41af84, 0x4d888205, 0x00201198, 0x463d835f, 0x152106d7,
|
||||
0x0a355a33, 0x6917614e, 0x75411f4d, 0x184b8b07, 0x1809c344, 0x21091640, 0x0b828000, 0x42808021, 0x26790519, 0x86058605, 0x2428422d, 0x22123b42,
|
||||
0x42000080, 0xf587513b, 0x7813677b, 0xaf4d139f, 0x00ff210c, 0x5e0a1d57, 0x3b421546, 0x01032736, 0x02000380, 0x41180480, 0x2f420f07, 0x0c624807,
|
||||
0x00000025, 0x18000103, 0x83153741, 0x430120c3, 0x042106b2, 0x088d4d00, 0x2f830620, 0x1810434a, 0x18140345, 0x8507fb41, 0x5ee582ea, 0x0023116c,
|
||||
0x8d000600, 0x053b56af, 0xa6554fa2, 0x0d704608, 0x40180d20, 0x47181a43, 0xd37b07ff, 0x0b79500c, 0x420fd745, 0x47450bd9, 0x8471830a, 0x095a777e,
|
||||
0x84137542, 0x82002013, 0x2f401800, 0x0007213b, 0x4405e349, 0x0d550ff3, 0x16254c0c, 0x820ffe4a, 0x0400218a, 0x89066f41, 0x106b414f, 0xc84d0120,
|
||||
0x80802206, 0x0c9a4b03, 0x00100025, 0x68000200, 0x9d8c2473, 0x44134344, 0xf36a0f33, 0x4678860f, 0x1b440a25, 0x41988c0a, 0x80201879, 0x43079b5e,
|
||||
0x4a18080b, 0x0341190b, 0x1259530c, 0x43251552, 0x908205c8, 0x0cac4018, 0x86000421, 0x0e504aa2, 0x0020b891, 0xfb450082, 0x51132014, 0x8f5205f3,
|
||||
0x35052108, 0x8505cb59, 0x0f6d4f70, 0x82150021, 0x29af5047, 0x4f004b24, 0x75795300, 0x1b595709, 0x460b6742, 0xbf4b0f0d, 0x5743870b, 0xcb6d1461,
|
||||
0x08f64505, 0x4e05ab6c, 0x334126c3, 0x0bcb6b0d, 0x1811034d, 0x4111ef4b, 0x814f1ce5, 0x20af8227, 0x07fd7b80, 0x41188e84, 0xef410f33, 0x80802429,
|
||||
0x410d0000, 0xa34205ab, 0x76b7881c, 0xff500b89, 0x0741430f, 0x20086f4a, 0x209d8200, 0x234c18fd, 0x05d4670a, 0x4509af51, 0x9642078d, 0x189e831d,
|
||||
0x7c1cc74b, 0xcd4c07b9, 0x0e7c440f, 0x8b7b0320, 0x21108210, 0xc76c8080, 0x03002106, 0x6b23bf41, 0xc549060b, 0x7946180b, 0x0ff7530f, 0x17ad4618,
|
||||
0x200ecd45, 0x208c83fd, 0x5e0488fe, 0x032009c6, 0x420d044e, 0x0d8f0d7f, 0x00820020, 0x18001021, 0x6d273b45, 0xfd4c0c93, 0xcf451813, 0x0fe5450f,
|
||||
0x5a47c382, 0x820a8b0a, 0x282b4998, 0x410a8b5b, 0x4b232583, 0x54004f00, 0x978f0ce3, 0x500f1944, 0xa95f1709, 0x0280220b, 0x05ba7080, 0xa1530682,
|
||||
0x06324c13, 0x91412582, 0x05536e2c, 0x63431020, 0x0f434706, 0x8c11374c, 0x176143d7, 0x4d0f454c, 0xd3680bed, 0x0bee4d17, 0x212b9a41, 0x0f530a00,
|
||||
0x140d531c, 0x43139143, 0x95610e8d, 0x0f094415, 0x4205fb56, 0x1b4205cf, 0x17015225, 0x5e0c477f, 0xaf6e0aeb, 0x0ff36218, 0x04849a84, 0x0a454218,
|
||||
0x9c430420, 0x23c6822b, 0x04000102, 0x45091b4b, 0xf05f0955, 0x82802007, 0x421c2023, 0x5218282b, 0x7b53173f, 0x0fe7480c, 0x74173b7f, 0x47751317,
|
||||
0x634d1807, 0x0f6f430f, 0x24086547, 0xfc808002, 0x0b3c7f80, 0x10840120, 0x188d1282, 0x20096b43, 0x0fc24403, 0x00260faf, 0x0180000b, 0x3f500280,
|
||||
0x18002019, 0x450b4941, 0xf3530fb9, 0x18002010, 0x8208a551, 0x06234d56, 0xcb58a39b, 0xc3421805, 0x1313461e, 0x0f855018, 0xd34b0120, 0x6cfe2008,
|
||||
0x574f0885, 0x09204114, 0x07000029, 0x00008000, 0x44028002, 0x01420f57, 0x10c95c10, 0x11184c18, 0x80221185, 0x7f421e00, 0x00732240, 0x09cd4977,
|
||||
0x6d0b2b42, 0x4f180f8f, 0x8f5a0bcb, 0x9b0f830f, 0x0fb9411f, 0x230b5756, 0x00fd8080, 0x82060745, 0x000121d5, 0x8e0fb277, 0x4a8d4211, 0x24061c53,
|
||||
0x04000007, 0x12275280, 0x430c954c, 0x80201545, 0x200f764f, 0x20008200, 0x20ce8308, 0x09534f02, 0x660edf64, 0x73731771, 0xe7411807, 0x20a2820c,
|
||||
0x13b64404, 0x8f5d6682, 0x1d6b4508, 0x0cff4d18, 0x3348c58f, 0x0fc34c07, 0x31558b84, 0x8398820f, 0x17514712, 0x240b0e46, 0x80000a00, 0x093b4502,
|
||||
0x420f9759, 0xa54c0bf1, 0x0f2b470c, 0x410d314b, 0x2584170c, 0x73b30020, 0xb55fe782, 0x204d8410, 0x08e043fe, 0x4f147e41, 0x022008ab, 0x4b055159,
|
||||
0x2950068f, 0x00022208, 0x48511880, 0x82002009, 0x00112300, 0x634dff00, 0x24415f27, 0x180f6d43, 0x4d0b5d45, 0x4d5f05ef, 0x01802317, 0x56188000,
|
||||
0xa7840807, 0xc6450220, 0x21ca8229, 0x4b781a00, 0x3359182c, 0x0cf3470f, 0x180bef46, 0x420b0354, 0xff470b07, 0x4515200a, 0x9758239b, 0x4a80200c,
|
||||
0xd2410a26, 0x05fb4a08, 0x4b05e241, 0x03200dc9, 0x92290941, 0x00002829, 0x00010900, 0x5b020001, 0x23201363, 0x460d776a, 0xef530fdb, 0x209a890c,
|
||||
0x13fc4302, 0x00008024, 0xc4820104, 0x08820220, 0x20086b5b, 0x18518700, 0x8408d349, 0x0da449a1, 0x00080024, 0x7b690280, 0x4c438b1a, 0x01220f63,
|
||||
0x4c878000, 0x5c149c53, 0xfb430868, 0x2f56181e, 0x0ccf7b1b, 0x0f075618, 0x2008e347, 0x14144104, 0x00207f83, 0x00207b82, 0x201adf47, 0x16c35a13,
|
||||
0x540fdf47, 0x802006c8, 0x5418f185, 0x29430995, 0x00002419, 0x58001600, 0x5720316f, 0x4d051542, 0x4b7b1b03, 0x138f4707, 0xb747b787, 0x4aab8213,
|
||||
0x058305fc, 0x20115759, 0x82128401, 0x0a0b44e8, 0x46800121, 0xe64210d0, 0x82129312, 0x4bffdffe, 0x3b41171b, 0x9b27870f, 0x808022ff, 0x085c68fe,
|
||||
0x41800021, 0x01410b20, 0x001a213a, 0x47480082, 0x11374e12, 0x56130b4c, 0xdf4b0c65, 0x0b0f590b, 0x0f574c18, 0x830feb4b, 0x075f480f, 0x480b4755,
|
||||
0x40490b73, 0x80012206, 0x09d74280, 0x80fe8022, 0x80210e86, 0x056643ff, 0x10820020, 0x420b2646, 0x0b58391a, 0xd74c1808, 0x078b4e22, 0x2007f55f,
|
||||
0x4b491807, 0x83802017, 0x65aa82a7, 0x3152099e, 0x068b7616, 0x9b431220, 0x09bb742c, 0x500e376c, 0x8342179b, 0x0a4d5d0f, 0x8020a883, 0x180cd349,
|
||||
0x2016bb4b, 0x14476004, 0x84136c43, 0x08cf7813, 0x4f4c0520, 0x156f420f, 0x20085f42, 0x6fd3be03, 0xd4d30803, 0xa7411420, 0x004b222c, 0x0d3b614f,
|
||||
0x3f702120, 0x1393410a, 0x8f132745, 0x47421827, 0x41e08209, 0xb05e2bb9, 0x18b7410c, 0x18082647, 0x4107a748, 0xeb8826bf, 0x0ca76018, 0x733ecb41,
|
||||
0xd0410d83, 0x43ebaf2a, 0x0420067f, 0x721dab4c, 0x472005bb, 0x4105d341, 0x334844cb, 0x20dba408, 0x47d6ac00, 0x034e3aef, 0x0f8f421b, 0x930f134d,
|
||||
0x3521231f, 0xb7421533, 0x42f5ad0a, 0x1e961eaa, 0x17000022, 0x4c367b50, 0x7d491001, 0x0bf5520f, 0x4c18fda7, 0xb8460c55, 0x83fe2005, 0x00fe25b9,
|
||||
0x80000180, 0x9e751085, 0x261b5c12, 0x82110341, 0x001123fb, 0x4518fe80, 0xf38c2753, 0x6d134979, 0x295107a7, 0xaf5f180f, 0x0fe3660c, 0x180b6079,
|
||||
0x2007bd5f, 0x9aab9103, 0x2f4d1811, 0x05002109, 0x44254746, 0x1d200787, 0x450bab75, 0x4f180f57, 0x4f181361, 0x3b831795, 0xeb4b0120, 0x0b734805,
|
||||
0x84078f48, 0x2e1b47bc, 0x00203383, 0xaf065f45, 0x831520d7, 0x130f51a7, 0x1797bf97, 0x2b47d783, 0x18fe2005, 0x4a18a44f, 0xa64d086d, 0x1ab0410d,
|
||||
0x6205a258, 0xdbab069f, 0x4f06f778, 0xa963081d, 0x133b670a, 0x8323d141, 0x13195b23, 0x530f5e70, 0xe5ad0824, 0x58001421, 0x1f472b4b, 0x47bf410c,
|
||||
0x82000121, 0x83fe20cb, 0x07424404, 0x68068243, 0xd7ad0d3d, 0x00010d26, 0x80020000, 0x4a1c6f43, 0x23681081, 0x10a14f13, 0x8a070e57, 0x430a848f,
|
||||
0x7372243e, 0x4397a205, 0xb56c1021, 0x43978f0f, 0x64180505, 0x99aa0ff2, 0x0e000022, 0x20223341, 0x094b4f37, 0x074a3320, 0x2639410a, 0xfe208e84,
|
||||
0x8b0e0048, 0x508020a3, 0x9e4308fe, 0x073f4115, 0xe3480420, 0x0c9b5f1b, 0x7c137743, 0x9a95185b, 0x6122b148, 0x979b08df, 0x0fe36c18, 0x48109358,
|
||||
0x23441375, 0x0ffd5c0b, 0x180fc746, 0x2011d157, 0x07e95702, 0x58180120, 0x18770ac3, 0x51032008, 0x7d4118e3, 0x80802315, 0x3b4c1900, 0xbb5a1830,
|
||||
0x0ceb6109, 0x5b0b3d42, 0x4f181369, 0x4f180b8d, 0x4f180f75, 0x355a1b81, 0x200d820d, 0x18e483fd, 0x4528854f, 0x89420846, 0x1321411f, 0x44086b60,
|
||||
0x07421d77, 0x107d4405, 0x4113fd41, 0x5a181bf1, 0x4f180db3, 0x8021128f, 0x20f68280, 0x44a882fe, 0x334d249a, 0x052f6109, 0x1520c3a7, 0xef4eb783,
|
||||
0x4ec39b1b, 0xc4c90ee7, 0x20060b4d, 0x256f4905, 0x4d0cf761, 0xcf9b1f13, 0xa213d74e, 0x0e1145d4, 0x50135b42, 0xcb4e398f, 0x20d79f27, 0x08865d80,
|
||||
0x186d5018, 0xa90f7142, 0x067342d7, 0x3f450420, 0x65002021, 0xe3560771, 0x24d38f23, 0x15333531, 0x0eb94d01, 0x451c9f41, 0x384322fb, 0x00092108,
|
||||
0x19af6b18, 0x6e0c6f5a, 0xbd770bfb, 0x22bb7718, 0x20090f57, 0x25e74204, 0x4207275a, 0xdb5408ef, 0x1769450f, 0x1b1b5518, 0x210b1f57, 0x5e4c8001,
|
||||
0x55012006, 0x802107f1, 0x0a306a80, 0x45808021, 0x0d850b88, 0x31744f18, 0x1808ec54, 0x2009575b, 0x45ffa505, 0x1b420c73, 0x180f9f0f, 0x4a0cf748,
|
||||
0x501805b2, 0x00210f40, 0x4d118f80, 0xd6823359, 0x072b5118, 0x314ad7aa, 0x8fc79f08, 0x45d78b1f, 0xfe20058f, 0x23325118, 0x7b54d9b5, 0x9fc38f46,
|
||||
0x10bb410f, 0x41077b42, 0xc1410faf, 0x27cf441d, 0x46051b4f, 0x04200683, 0x2121d344, 0x8f530043, 0x8fcf9f0e, 0x21df8c1f, 0x50188000, 0x5d180e52,
|
||||
0xfd201710, 0x4405c341, 0xd68528e3, 0x20071f6b, 0x1b734305, 0x6b080957, 0x7d422b1f, 0x67002006, 0x7f8317b1, 0x2024cb48, 0x08676e00, 0x8749a39b,
|
||||
0x18132006, 0x410a6370, 0x8f490b47, 0x7e1f8f13, 0x551805c3, 0x4c180915, 0xfe200e2f, 0x244d5d18, 0x270bcf44, 0xff000019, 0x04800380, 0x5f253342,
|
||||
0xff520df7, 0x13274c18, 0x5542dd93, 0x0776181b, 0xf94a1808, 0x084a4c0c, 0x4308ea5b, 0xde831150, 0x7900fd21, 0x00492c1e, 0x060f4510, 0x17410020,
|
||||
0x0ce74526, 0x6206b341, 0x1f561083, 0x9d6c181b, 0x08a0500e, 0x112e4118, 0x60000421, 0xbf901202, 0x4408e241, 0xc7ab0513, 0xb40f0950, 0x055943c7,
|
||||
0x4f18ff20, 0xc9ae1cad, 0x32b34f18, 0x7a180120, 0x3d520a05, 0x53d1b40a, 0x80200813, 0x1b815018, 0x832bf86f, 0x67731847, 0x297f4308, 0x6418d54e,
|
||||
0x734213f7, 0x056b4b27, 0xdba5fe20, 0x1828aa4e, 0x2031a370, 0x06cb6101, 0x2040ad41, 0x07365300, 0x2558d985, 0x83fe200c, 0x0380211c, 0x542c4743,
|
||||
0x052006b7, 0x6021df45, 0x897b0707, 0x18d3c010, 0x20090e70, 0x1d5843ff, 0x540a0e44, 0x002126c5, 0x322f7416, 0x636a5720, 0x0f317409, 0x610fe159,
|
||||
0x294617e7, 0x08555213, 0x2006a75d, 0x6cec84fd, 0xfb5907be, 0x3a317405, 0x83808021, 0x180f20ea, 0x4626434a, 0x531818e3, 0xdb59172d, 0x0cbb460c,
|
||||
0x2013d859, 0x18b94502, 0x8f46188d, 0x77521842, 0x0a184e38, 0x9585fd20, 0x6a180684, 0xc64507e9, 0x51cbb230, 0xd3440cf3, 0x17ff6a0f, 0x450f5b42,
|
||||
0x276407c1, 0x4853180a, 0x21ccb010, 0xcf580013, 0x0c15442d, 0x410a1144, 0x1144359d, 0x5cfe2006, 0xa1410a43, 0x2bb64519, 0x2f5b7618, 0xb512b745,
|
||||
0x0cfd6fd1, 0x42089f59, 0xb8450c70, 0x0000232d, 0x50180900, 0xb9491ae3, 0x0fc37610, 0x01210f83, 0x0f3b4100, 0xa01b2742, 0x0ccd426f, 0x6e8f6f94,
|
||||
0x9c808021, 0xc7511870, 0x17c74b08, 0x9b147542, 0x44fe2079, 0xd5480c7e, 0x95ef861d, 0x101b597b, 0xf5417594, 0x9f471808, 0x86868d0e, 0x3733491c,
|
||||
0x690f4d6d, 0x43440b83, 0x1ba94c0b, 0x660cd16b, 0x802008ae, 0x74126448, 0xcb4f38a3, 0x2cb74b0b, 0x47137755, 0xe3971777, 0x1b5d0120, 0x057a4108,
|
||||
0x6e08664d, 0x17421478, 0x11af4208, 0x850c3f42, 0x08234f0c, 0x4321eb4a, 0xf3451095, 0x0f394e0f, 0x4310eb45, 0xc09707b1, 0x54431782, 0xaec08d1d,
|
||||
0x0f434dbb, 0x9f0c0b45, 0x0a3b4dbb, 0x4618bdc7, 0x536032eb, 0x17354213, 0x4d134169, 0xc7a30c2f, 0x4e254342, 0x174332cf, 0x43cdae17, 0x6b4706e4,
|
||||
0x0e16430d, 0x530b5542, 0x2f7c26bb, 0x13075f31, 0x43175342, 0x60181317, 0x6550114e, 0x28624710, 0x58070021, 0x59181683, 0x2d540cf5, 0x05d5660c,
|
||||
0x20090c7b, 0x0e157e02, 0x8000ff2b, 0x14000080, 0x80ff8000, 0x27137e03, 0x336a4b20, 0x0f817107, 0x13876e18, 0x730f2f7e, 0x2f450b75, 0x6d02200b,
|
||||
0x6d66094c, 0x4b802009, 0x15820a02, 0x2f45fe20, 0x5e032006, 0x00202fd9, 0x450af741, 0xeb412e0f, 0x0ff3411f, 0x420a8b65, 0xf7410eae, 0x1c664810,
|
||||
0x540e1145, 0xbfa509f3, 0x42302f58, 0x80200c35, 0xcb066c47, 0x4b1120c1, 0x41492abb, 0x34854110, 0xa7097b72, 0x251545c7, 0x4b2c7f56, 0xc5b40bab,
|
||||
0x940cd54e, 0x2e6151c8, 0x09f35f18, 0x4b420420, 0x09677121, 0x8f24f357, 0x1b5418e1, 0x08915a1f, 0x3143d894, 0x22541805, 0x1b9b4b0e, 0x8c0d3443,
|
||||
0x1400240d, 0x18ff8000, 0x582e6387, 0xf99b2b3b, 0x8807a550, 0x17a14790, 0x2184fd20, 0x5758fe20, 0x2354882c, 0x15000080, 0x5e056751, 0x334c2c2f,
|
||||
0x97c58f0c, 0x1fd7410f, 0x0d4d4018, 0x4114dc41, 0x04470ed6, 0x0dd54128, 0x00820020, 0x02011523, 0x22008700, 0x86480024, 0x0001240a, 0x8682001a,
|
||||
0x0002240b, 0x866c000e, 0x8a03200b, 0x8a042017, 0x0005220b, 0x22218614, 0x84060000, 0x86012017, 0x8212200f, 0x250b8519, 0x000d0001, 0x0b850031,
|
||||
0x07000224, 0x0b862600, 0x11000324, 0x0b862d00, 0x238a0420, 0x0a000524, 0x17863e00, 0x17840620, 0x01000324, 0x57820904, 0x0b85a783, 0x0b85a785,
|
||||
0x0b85a785, 0x22000325, 0x85007a00, 0x85a7850b, 0x85a7850b, 0x22a7850b, 0x82300032, 0x00342201, 0x0805862f, 0x35003131, 0x54207962, 0x74736972,
|
||||
0x47206e61, 0x6d6d6972, 0x65527265, 0x616c7567, 0x58545472, 0x6f725020, 0x43796767, 0x6e61656c, 0x30325454, 0x822f3430, 0x35313502, 0x79006200,
|
||||
0x54002000, 0x69007200, 0x74007300, 0x6e006100, 0x47200f82, 0x6d240f84, 0x65006d00, 0x52200982, 0x67240582, 0x6c007500, 0x72201d82, 0x54222b82,
|
||||
0x23825800, 0x19825020, 0x67006f22, 0x79220182, 0x1b824300, 0x3b846520, 0x1f825420, 0x41000021, 0x1422099b, 0x0b410000, 0x87088206, 0x01012102,
|
||||
0x78080982, 0x01020101, 0x01040103, 0x01060105, 0x01080107, 0x010a0109, 0x010c010b, 0x010e010d, 0x0110010f, 0x01120111, 0x01140113, 0x01160115,
|
||||
0x01180117, 0x011a0119, 0x011c011b, 0x011e011d, 0x0020011f, 0x00040003, 0x00060005, 0x00080007, 0x000a0009, 0x000c000b, 0x000e000d, 0x0010000f,
|
||||
0x00120011, 0x00140013, 0x00160015, 0x00180017, 0x001a0019, 0x001c001b, 0x001e001d, 0x08bb821f, 0x22002142, 0x24002300, 0x26002500, 0x28002700,
|
||||
0x2a002900, 0x2c002b00, 0x2e002d00, 0x30002f00, 0x32003100, 0x34003300, 0x36003500, 0x38003700, 0x3a003900, 0x3c003b00, 0x3e003d00, 0x40003f00,
|
||||
0x42004100, 0x4b09f382, 0x00450044, 0x00470046, 0x00490048, 0x004b004a, 0x004d004c, 0x004f004e, 0x00510050, 0x00530052, 0x00550054, 0x00570056,
|
||||
0x00590058, 0x005b005a, 0x005d005c, 0x005f005e, 0x01610060, 0x01220121, 0x01240123, 0x01260125, 0x01280127, 0x012a0129, 0x012c012b, 0x012e012d,
|
||||
0x0130012f, 0x01320131, 0x01340133, 0x01360135, 0x01380137, 0x013a0139, 0x013c013b, 0x013e013d, 0x0140013f, 0x00ac0041, 0x008400a3, 0x00bd0085,
|
||||
0x00e80096, 0x008e0086, 0x009d008b, 0x00a400a9, 0x008a00ef, 0x008300da, 0x00f20093, 0x008d00f3, 0x00880097, 0x00de00c3, 0x009e00f1, 0x00f500aa,
|
||||
0x00f600f4, 0x00ad00a2, 0x00c700c9, 0x006200ae, 0x00900063, 0x00cb0064, 0x00c80065, 0x00cf00ca, 0x00cd00cc, 0x00e900ce, 0x00d30066, 0x00d100d0,
|
||||
0x006700af, 0x009100f0, 0x00d400d6, 0x006800d5, 0x00ed00eb, 0x006a0089, 0x006b0069, 0x006c006d, 0x00a0006e, 0x0071006f, 0x00720070, 0x00750073,
|
||||
0x00760074, 0x00ea0077, 0x007a0078, 0x007b0079, 0x007c007d, 0x00a100b8, 0x007e007f, 0x00810080, 0x00ee00ec, 0x6e750eba, 0x646f6369, 0x78302365,
|
||||
0x31303030, 0x32200e8d, 0x33200e8d, 0x34200e8d, 0x35200e8d, 0x36200e8d, 0x37200e8d, 0x38200e8d, 0x39200e8d, 0x61200e8d, 0x62200e8d, 0x63200e8d,
|
||||
0x64200e8d, 0x65200e8d, 0x66200e8d, 0x31210e8c, 0x8d0e8d30, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef,
|
||||
0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x66312def, 0x6c656406, 0x04657465, 0x6f727545, 0x3820ec8c, 0x3820ec8d,
|
||||
0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d,
|
||||
0x3820ec8d, 0x200ddc41, 0x0ddc4139, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920,
|
||||
0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0x00663923, 0x48fa0500, 0x00f762f9,
|
||||
const unsigned char font_proggyClean_compressed_data[]={
|
||||
0x78,0xda,0xdd,0x3d,0x69,0x90,0x54,0xc7,0x79,0x5f,0xbf,0xf7,
|
||||
0x66,0x67,0x17,0x96,0x65,0xd9,0x83,0xfb,0xd8,0x85,0x5d,0xee,
|
||||
0x63,0x1f,0x03,0xcb,0x0c,0x87,0x58,0x40,0x08,0xac,0x28,0x12,
|
||||
0x11,0x18,0xe1,0x58,0x91,0xb4,0xc0,0x72,0xd8,0x5c,0x81,0x05,
|
||||
0x81,0xec,0xc8,0x4f,0x87,0x65,0x19,0xc7,0x32,0x56,0xaa,0x88,
|
||||
0xa2,0x38,0x2a,0x47,0x71,0x51,0x89,0x8a,0x60,0x25,0xe5,0x52,
|
||||
0x28,0xc7,0xae,0x4a,0x95,0x13,0x85,0x24,0x8a,0xa3,0xd8,0x92,
|
||||
0xad,0xd2,0x0f,0x47,0x95,0x1f,0x2e,0x19,0x2b,0x58,0x49,0x64,
|
||||
0x97,0x7e,0x68,0x67,0xd2,0xef,0xee,0xee,0xd7,0xdd,0xaf,0xbb,
|
||||
0x67,0xd6,0x3f,0x32,0xbb,0x33,0xef,0x98,0x99,0xf7,0xfa,0x3b,
|
||||
0xfa,0xbb,0xfb,0x1b,0x40,0x00,0xd0,0x0a,0x1e,0xd8,0x30,0x74,
|
||||
0xcf,0xee,0x55,0xab,0x9f,0xfe,0xf9,0xe8,0x25,0x00,0xb4,0x13,
|
||||
0x9f,0xbd,0xfb,0xc0,0xf1,0xe1,0x53,0x56,0xc7,0x82,0xb3,0x00,
|
||||
0xf6,0xd7,0xf1,0xb9,0x7b,0x0f,0x9c,0x1b,0xed,0x81,0xe0,0xe1,
|
||||
0x7c,0x84,0x5f,0xac,0xc3,0xc7,0x2e,0x1c,0xea,0xf8,0xe6,0x17,
|
||||
0xf7,0x02,0x14,0x1d,0x80,0x67,0xbd,0x23,0x23,0xc3,0x07,0x7f,
|
||||
0xfc,0xd5,0x43,0x3f,0xc4,0xef,0xbd,0x86,0x9f,0x83,0x47,0xf0,
|
||||
0x89,0xe6,0xad,0xe8,0x7b,0xf8,0xbb,0xf8,0x7d,0xe8,0x3b,0x72,
|
||||
0x7c,0xf4,0xfc,0x45,0x78,0xd4,0xc3,0xc7,0xcf,0xe1,0xaf,0x37,
|
||||
0x1d,0x3b,0x79,0x60,0xf8,0xf7,0xcf,0xbc,0xfc,0x16,0x40,0xc1,
|
||||
0xbf,0x9c,0x73,0x7c,0xf8,0xfc,0x29,0x74,0x0d,0xde,0xc6,0xef,
|
||||
0x2f,0xc6,0x27,0x7a,0x4e,0x0c,0x1f,0x1f,0xe9,0xff,0xc4,0xdf,
|
||||
0x5e,0x06,0xf8,0xa3,0x27,0xf1,0xb9,0x17,0x4e,0x9d,0x3c,0x33,
|
||||
0x7a,0xe5,0xea,0x13,0xbf,0x00,0xf8,0xe3,0x3e,0xfc,0x9d,0x1f,
|
||||
0x9c,0x3a,0x3d,0x72,0xea,0xa8,0x85,0x3a,0xf0,0x78,0x3e,0xc0,
|
||||
0x9f,0x6f,0x06,0x1f,0x16,0xfc,0xdc,0xf8,0xf1,0x9f,0xbd,0xf9,
|
||||
0xe0,0xe4,0x8d,0xbf,0x04,0xbb,0x39,0x18,0xed,0xdf,0x1c,0x7e,
|
||||
0xf8,0x49,0x7f,0xfb,0xdd,0x67,0xaf,0xfc,0x18,0xa0,0xea,0xd9,
|
||||
0x9e,0x7f,0x3f,0x0c,0xb1,0x15,0x42,0xe3,0x7f,0xc7,0xf9,0xbb,
|
||||
0xea,0x10,0x3e,0xe5,0x05,0x6f,0x78,0xc1,0x95,0xc8,0x87,0xe5,
|
||||
0x9f,0x41,0x08,0x2e,0x41,0x5f,0x74,0xdc,0x0c,0x43,0x30,0x01,
|
||||
0xef,0x9d,0x83,0xf0,0x26,0xf8,0x5b,0xe8,0x92,0x0f,0x88,0xf5,
|
||||
0x1d,0xeb,0x22,0x3e,0xfc,0x4a,0xb8,0x45,0xff,0x00,0xab,0xc3,
|
||||
0xdb,0x38,0x2d,0xc0,0x7d,0x6c,0x39,0x36,0x7a,0x06,0x5f,0x0b,
|
||||
0x7a,0xae,0x86,0x17,0x2a,0x00,0xf2,0xc2,0x91,0xd8,0x5e,0xfd,
|
||||
0x7f,0xc8,0x0b,0x40,0xf1,0xe1,0x0a,0xf6,0x91,0xbf,0x1f,0xfc,
|
||||
0xa5,0x7b,0xf4,0x1f,0xf2,0xc2,0x4f,0x03,0xb9,0xf5,0x32,0xdf,
|
||||
0xa2,0xdf,0x09,0xef,0x10,0xdf,0x27,0x7a,0x02,0x20,0xc1,0xf7,
|
||||
0xa3,0x31,0xb1,0x57,0x05,0x7a,0x0c,0x18,0x07,0x3e,0x04,0xc0,
|
||||
0x19,0x6b,0xf4,0x9e,0x4d,0xc3,0x04,0xc9,0x35,0x82,0xf7,0x03,
|
||||
0x9a,0xc4,0xef,0xf8,0x58,0x25,0xee,0x6b,0xc7,0xe3,0x8d,0xef,
|
||||
0x17,0xdc,0x05,0xb1,0x30,0x09,0x8e,0xfd,0x7b,0x22,0x60,0xa1,
|
||||
0xe0,0x60,0x24,0xef,0xfb,0x5e,0xce,0x5f,0xc8,0xa7,0xe1,0x63,
|
||||
0x76,0xc4,0x95,0x77,0xe1,0x33,0x28,0x38,0x76,0x60,0x20,0xe0,
|
||||
0xfb,0xe6,0x80,0x93,0x3f,0x07,0xb5,0x9e,0xab,0xb5,0x5a,0xf0,
|
||||
0x99,0xc7,0x82,0x3d,0x7c,0x8b,0xff,0x78,0x93,0xe4,0x65,0xd4,
|
||||
0x04,0xff,0x9f,0x1f,0x8f,0xa9,0x7d,0xec,0xaf,0x00,0x7d,0xf9,
|
||||
0x3a,0xaa,0x7d,0x3e,0x3a,0x7c,0xb5,0x01,0x7f,0x1f,0xa0,0xd9,
|
||||
0xe8,0x05,0xab,0xcb,0x7a,0xda,0xfa,0xc8,0xee,0xb2,0xf7,0xd9,
|
||||
0x5f,0xb3,0x7f,0xe2,0x74,0x39,0xab,0x9d,0x5d,0xce,0x7e,0xe7,
|
||||
0xc5,0xc2,0xd4,0xc2,0xa1,0xc2,0x77,0x9a,0x3a,0x9a,0x46,0x9b,
|
||||
0x7e,0x54,0x2c,0x17,0x1f,0x2d,0xbe,0xd7,0x7c,0x77,0xf3,0xb1,
|
||||
0xe6,0xcb,0xcd,0xaf,0xb7,0xb4,0xb7,0xdc,0xd9,0xf2,0xf4,0x84,
|
||||
0xa9,0x13,0xbc,0x89,0xce,0xc4,0xbd,0x13,0x6f,0xb4,0xae,0x6c,
|
||||
0x7d,0xbc,0xf5,0xe6,0xa4,0x07,0x26,0x7d,0x63,0xd2,0xcd,0xb6,
|
||||
0x5d,0x6d,0x97,0x27,0x2f,0x9e,0xfc,0x72,0x7b,0x47,0xfb,0x68,
|
||||
0xfb,0x3b,0x53,0xee,0x9d,0xf2,0x4a,0x87,0xd3,0x71,0xa2,0xe3,
|
||||
0xef,0x3b,0xef,0xea,0xbc,0xda,0xf9,0xab,0xae,0x7d,0x5d,0xd7,
|
||||
0xba,0x6e,0x76,0x0f,0x75,0x7b,0xdd,0x57,0xba,0xaf,0x4f,0xed,
|
||||
0x98,0xfa,0xe8,0xd4,0x57,0xa7,0xad,0x99,0xf6,0xcc,0xb4,0x77,
|
||||
0xa6,0xef,0x9d,0xfe,0xed,0xe9,0xb7,0x66,0x0c,0xce,0xb8,0x3c,
|
||||
0xe3,0x8d,0x99,0x3b,0x67,0x7e,0x6d,0xe6,0xfb,0xb3,0xee,0x9f,
|
||||
0x75,0x63,0xb6,0x33,0xfb,0xae,0xd9,0x97,0x67,0xdf,0x9c,0xb3,
|
||||
0x74,0xce,0xb3,0x73,0x7e,0x30,0x77,0x68,0xee,0x33,0x73,0xdf,
|
||||
0x99,0xd7,0x37,0xef,0xdc,0xbc,0x2b,0xf3,0xae,0xf4,0xb4,0xe3,
|
||||
0xbf,0x95,0x3d,0x17,0x7b,0xfe,0xba,0xe7,0x46,0x6f,0x57,0xef,
|
||||
0x68,0xef,0x73,0xbd,0xb7,0xe6,0xef,0x9f,0xff,0xd4,0x82,0x56,
|
||||
0xfc,0xe7,0x05,0x7f,0xcf,0x2d,0x78,0x79,0xc1,0x5b,0x7d,0xd0,
|
||||
0x77,0x67,0xdf,0x91,0xbe,0x4b,0x7d,0xd7,0xfa,0x9b,0xfa,0x1f,
|
||||
0xea,0x7f,0xbc,0xff,0xc3,0xfe,0x0f,0x17,0xee,0x5b,0xf8,0x12,
|
||||
0xfe,0x7b,0x6b,0xd1,0xd0,0xa2,0xe7,0x17,0x4f,0x58,0x7c,0x64,
|
||||
0xf1,0x9f,0x2f,0x69,0x5b,0xd2,0xb3,0xe4,0xfa,0x92,0x0f,0x97,
|
||||
0x0e,0x2e,0x7d,0x68,0xe9,0x43,0xcb,0xac,0x65,0x4b,0x97,0x3d,
|
||||
0xb0,0xec,0xea,0xb2,0x9f,0x2e,0xef,0x59,0xbe,0x66,0xf9,0xf3,
|
||||
0x2b,0x16,0xaf,0xb8,0x7f,0xc5,0xf9,0x15,0x2f,0xad,0x78,0x77,
|
||||
0xe5,0xc2,0x95,0x57,0x56,0x2d,0x5c,0xf5,0xca,0xaa,0x0f,0x06,
|
||||
0x1e,0x18,0xb8,0xe1,0xde,0xe6,0x7e,0x6b,0xf5,0xdc,0xd5,0x2f,
|
||||
0x94,0xe6,0x96,0x1e,0x2f,0xdd,0x5a,0x73,0xff,0x9a,0xef,0xaf,
|
||||
0x5d,0xbf,0xf6,0xa9,0xb5,0x6f,0x0c,0x2e,0x1c,0x3c,0x3d,0xf8,
|
||||
0xd3,0x75,0xe7,0xd6,0xbd,0x55,0x5e,0x5f,0xbe,0x52,0xe9,0xa8,
|
||||
0x8c,0x56,0xae,0xad,0x5f,0xb9,0xfe,0xf9,0x0d,0x4d,0x1b,0x3e,
|
||||
0xbb,0xe1,0xdd,0x8d,0xeb,0x37,0x5e,0xde,0x34,0x7f,0xd3,0x53,
|
||||
0x9b,0xde,0xbb,0x6d,0xef,0x6d,0xaf,0x6e,0x5e,0xba,0xf9,0xf9,
|
||||
0xa1,0x8e,0xa1,0x4f,0x0d,0xbd,0xbe,0x65,0x70,0xcb,0x8b,0x5b,
|
||||
0x9b,0xb7,0x0e,0x6d,0x7d,0x64,0xeb,0xf5,0xad,0xef,0x6f,0xdb,
|
||||
0xbf,0xed,0xb5,0xdb,0x97,0xde,0x7e,0xf1,0xf6,0x5b,0xdb,0xf7,
|
||||
0x6d,0x7f,0x65,0xfb,0x7f,0xde,0xb1,0xe7,0x8e,0x6f,0xed,0xe8,
|
||||
0xda,0xf1,0xc8,0x8e,0xb7,0x77,0xee,0xd9,0xf9,0xea,0xc7,0x86,
|
||||
0x7c,0x99,0x1e,0x69,0x05,0x1b,0x8a,0x30,0x11,0x26,0x43,0x27,
|
||||
0x4c,0x83,0x59,0x30,0x0f,0x16,0xc0,0x22,0x58,0x06,0xab,0xa0,
|
||||
0x04,0xeb,0x60,0x03,0x6c,0x86,0x6d,0xb0,0x03,0x7e,0x03,0xee,
|
||||
0x81,0xdd,0x70,0x1f,0x7c,0x12,0x1e,0x84,0x03,0x70,0x18,0x3e,
|
||||
0x0d,0x27,0xe1,0x0c,0x3c,0x0c,0x9f,0xc1,0x33,0xf0,0x09,0xf8,
|
||||
0x02,0x7c,0x09,0xbe,0x02,0x30,0x65,0x6d,0xa9,0xdb,0x15,0x3c,
|
||||
0x0b,0xf8,0xd9,0x3b,0x4e,0x5b,0xd1,0x3d,0xbd,0xf0,0xf1,0x91,
|
||||
0xe7,0x59,0x75,0xbf,0x86,0x0f,0xc7,0x1b,0x8f,0x07,0x14,0x7d,
|
||||
0x59,0x6c,0x61,0xd1,0xc6,0xd0,0x02,0x10,0x86,0xa2,0xc8,0x79,
|
||||
0xda,0xf8,0x89,0xe8,0x8b,0xd8,0xd9,0xeb,0xd6,0x00,0x5f,0xbb,
|
||||
0x09,0xf9,0x4a,0x1f,0x8f,0x9c,0xba,0x76,0x70,0xe5,0x52,0x84,
|
||||
0x3f,0x72,0x8b,0xf0,0x77,0xbc,0xaa,0x17,0xbf,0x38,0xc0,0x0c,
|
||||
0x15,0xa6,0x87,0x7a,0xdf,0xd1,0xe7,0x1b,0xee,0x3d,0x45,0xbc,
|
||||
0x62,0xf2,0x39,0x94,0x0c,0x7b,0x2c,0x1a,0xee,0x98,0xe4,0x8c,
|
||||
0x6d,0x4c,0x2e,0xe8,0x06,0xaf,0xe6,0xd9,0xa0,0x85,0x83,0x00,
|
||||
0xfa,0x82,0x06,0xa4,0x79,0x58,0x28,0x84,0x10,0xd7,0x80,0x06,
|
||||
0x2b,0x38,0xae,0x01,0x0d,0x77,0x0d,0x8c,0xc0,0xf5,0x49,0xdd,
|
||||
0xa5,0x4d,0x6f,0xe8,0x24,0xe6,0x66,0x89,0x81,0x82,0xdc,0x2f,
|
||||
0x4a,0xde,0x2b,0x11,0x73,0xdc,0xc3,0xb6,0x8a,0x37,0x06,0x1e,
|
||||
0x41,0xc7,0x6a,0xcc,0x97,0x55,0xea,0xf4,0x98,0x6f,0xd6,0xe8,
|
||||
0x83,0x1a,0xc2,0xe9,0xe9,0xc2,0x89,0x24,0xb2,0xcd,0x65,0xce,
|
||||
0x95,0x72,0x64,0x57,0x3c,0xf7,0x30,0xd1,0xf0,0xa6,0x0a,0xc1,
|
||||
0xab,0x17,0x1c,0x8c,0x05,0x07,0x31,0x70,0x63,0x01,0x36,0x22,
|
||||
0xb0,0x0d,0x20,0xb5,0x91,0xe7,0x3b,0x01,0x89,0x3c,0xa0,0x64,
|
||||
0x4c,0x24,0x53,0xd2,0x59,0x0f,0x30,0x11,0x41,0x2d,0x2b,0x3f,
|
||||
0x52,0xbc,0x24,0x7c,0x5d,0x24,0xb6,0xc4,0x73,0x0e,0x22,0xb6,
|
||||
0x16,0x10,0xfc,0x99,0x3e,0x58,0x29,0xc3,0x1b,0xb7,0xca,0x38,
|
||||
0xa8,0x7b,0xb1,0x32,0x93,0x1c,0x23,0x82,0x8c,0xa0,0xf4,0x5f,
|
||||
0x94,0xc6,0x11,0x58,0xd2,0xbe,0x81,0x9a,0x83,0x8f,0x92,0x64,
|
||||
0x4e,0x97,0xd2,0xf9,0x5b,0x25,0xf8,0x38,0xa2,0x6a,0x35,0x50,
|
||||
0x3a,0x92,0x31,0xb4,0x48,0xc6,0x90,0xd0,0xb3,0x20,0x90,0x98,
|
||||
0x45,0x4a,0x52,0x46,0x1b,0x4b,0x78,0x2f,0xc7,0x27,0x59,0xe0,
|
||||
0x51,0xc5,0xf7,0x82,0x7e,0x06,0xab,0x11,0x36,0x19,0xa2,0x06,
|
||||
0x6e,0x9d,0x17,0x72,0x1b,0x31,0xce,0x40,0x3a,0xf0,0x35,0x35,
|
||||
0xa9,0xd1,0xc0,0x0a,0x1c,0xdb,0xf8,0xbe,0xc9,0x3d,0x09,0xca,
|
||||
0x01,0xf6,0x45,0x43,0x39,0xcc,0xe7,0x09,0x0a,0x13,0xb2,0xad,
|
||||
0x45,0xcb,0xcd,0xf4,0x25,0x87,0x1f,0x22,0x99,0x01,0x26,0x32,
|
||||
0x43,0x24,0x37,0x64,0x72,0x90,0x27,0x37,0x50,0xc4,0x37,0x89,
|
||||
0x64,0x18,0xf3,0x28,0x81,0xe8,0x31,0x32,0xc3,0x48,0x36,0xb6,
|
||||
0x29,0xc1,0x49,0x69,0x38,0x52,0xc6,0xb3,0xb3,0x90,0xa5,0x7e,
|
||||
0xa4,0xc5,0xaa,0xe4,0x6d,0xab,0x9e,0xba,0x80,0xc3,0xe3,0x51,
|
||||
0xa3,0x03,0x17,0xfb,0xf1,0xa8,0xc8,0x67,0x91,0x37,0xca,0x14,
|
||||
0xd3,0xc1,0x78,0x93,0x7f,0x4f,0x47,0x14,0x37,0x66,0xac,0x2e,
|
||||
0x21,0xe3,0x72,0xb8,0x22,0x41,0xa5,0x3e,0x13,0xc0,0x14,0x0d,
|
||||
0x9d,0xc8,0xa5,0xbe,0xaa,0xb5,0x4e,0xcc,0xc4,0x84,0x13,0x42,
|
||||
0x1d,0x48,0x31,0x75,0x88,0x6d,0x5b,0x8b,0x79,0x3b,0xb4,0xe6,
|
||||
0x28,0x57,0x3a,0x91,0x5a,0x8d,0x38,0x2f,0xa5,0x00,0x35,0x0b,
|
||||
0x4d,0x09,0x10,0x03,0x31,0x45,0x03,0x06,0xca,0x2a,0xe1,0xf1,
|
||||
0xb2,0x8a,0x27,0x85,0x42,0xb6,0x89,0x99,0x9b,0x91,0x2f,0x06,
|
||||
0x50,0x84,0xf1,0x56,0x39,0x0c,0x5c,0xdc,0xcb,0xe4,0x36,0xab,
|
||||
0xbe,0x55,0xf9,0x03,0xdf,0x59,0x4f,0x6e,0xe7,0x4a,0x6d,0x2d,
|
||||
0xdc,0xb2,0x12,0xbb,0x0a,0x0d,0x41,0x71,0xc4,0xef,0x46,0xbc,
|
||||
0xe2,0x6a,0x78,0xd8,0xa4,0xbc,0x14,0x69,0xa0,0xd4,0x42,0xf5,
|
||||
0x49,0x52,0xd5,0xe5,0x15,0x27,0xf4,0x87,0x09,0xfb,0x26,0xd1,
|
||||
0xe5,0x36,0x6d,0xa9,0x26,0x96,0x4b,0x35,0xfe,0x6e,0x53,0x68,
|
||||
0xaf,0x30,0xb6,0x51,0xe6,0xfb,0x1c,0x4b,0x10,0x8f,0x94,0xbe,
|
||||
0x58,0x82,0x53,0x3f,0xe6,0x2d,0xb6,0xf9,0xa8,0x19,0xe7,0x32,
|
||||
0x12,0x9a,0xd8,0xfa,0xd6,0x6f,0x80,0x96,0x18,0x35,0x96,0x8c,
|
||||
0x8e,0xad,0xbe,0xf8,0xb3,0xf1,0x67,0xf4,0xe6,0x4b,0x40,0x11,
|
||||
0x79,0x3c,0x64,0x2c,0xbe,0x3d,0x64,0x6c,0x60,0xda,0xb6,0x0a,
|
||||
0xa2,0xcd,0x02,0x98,0x3b,0x05,0x30,0x32,0x38,0xe8,0x26,0xdc,
|
||||
0x34,0xff,0x29,0x05,0x39,0xb8,0xa7,0x98,0x77,0x73,0xb5,0x77,
|
||||
0x12,0x19,0xc9,0x6a,0x6a,0xa9,0x86,0x0e,0xe2,0x24,0x33,0x8d,
|
||||
0xe3,0x1a,0x7e,0x3c,0x4c,0x3a,0x93,0x5c,0x8e,0x4d,0x27,0x3a,
|
||||
0xee,0xa5,0xaf,0x33,0x07,0x89,0xad,0x90,0xd8,0x2f,0x4c,0xc3,
|
||||
0x53,0xe4,0x4e,0xe8,0x32,0x7a,0x66,0x6e,0x22,0x57,0x87,0xaa,
|
||||
0xe2,0x86,0x3b,0x1f,0x64,0x12,0x45,0x24,0x79,0x90,0x97,0x98,
|
||||
0x03,0xa9,0x4f,0x1c,0x87,0x3b,0xac,0xc0,0x31,0x4e,0x5e,0x6d,
|
||||
0x5d,0x9b,0x76,0xba,0xb6,0xbf,0x9f,0xc4,0xb1,0x3a,0x15,0xc6,
|
||||
0xef,0x1a,0x68,0x5d,0x6a,0x9e,0xf2,0x6d,0x7a,0x06,0xea,0x31,
|
||||
0xa8,0x8f,0xbe,0x89,0x6d,0xef,0xa9,0xd8,0xf6,0x3c,0x58,0x58,
|
||||
0x4f,0x9f,0x67,0x49,0xa4,0xfc,0xea,0x25,0x8e,0x9e,0xba,0x76,
|
||||
0x33,0x8b,0xcd,0x74,0x36,0x20,0xfe,0x2c,0xa6,0x49,0x96,0x0c,
|
||||
0xe1,0x6b,0x42,0x2b,0x7d,0x37,0x4b,0xdb,0x26,0xd1,0xb0,0x54,
|
||||
0x33,0x71,0x19,0xbe,0x66,0x48,0xad,0xd5,0x2a,0xc8,0x23,0xcb,
|
||||
0x39,0xf4,0x52,0xf6,0x71,0xea,0x81,0x41,0x38,0x66,0x7b,0xbc,
|
||||
0xe5,0x9a,0x68,0x0e,0xf4,0x2a,0xca,0x84,0xec,0x9c,0x88,0xe3,
|
||||
0x7b,0x16,0xd4,0xe1,0x25,0x18,0xcf,0x93,0x5e,0x4d,0x4f,0x4d,
|
||||
0x36,0x6f,0x44,0x22,0x8a,0x3f,0x5f,0x2c,0x30,0x0a,0x48,0xb4,
|
||||
0xfa,0xb1,0x21,0x4b,0x06,0x67,0x86,0x56,0xc5,0x9c,0x58,0x04,
|
||||
0xca,0x84,0x25,0x15,0x7d,0x89,0xc0,0xaf,0x51,0x1f,0x4b,0x51,
|
||||
0x75,0x2c,0x54,0x30,0x44,0x6d,0x28,0x7a,0xfe,0xba,0x8c,0xf2,
|
||||
0x25,0x45,0xbf,0xc6,0xa3,0xe4,0x5e,0xac,0x9e,0xe3,0xf4,0x51,
|
||||
0xa4,0xb4,0x63,0x89,0xa9,0xe7,0xb7,0x2b,0xfa,0x8b,0x45,0xc9,
|
||||
0x53,0x60,0xff,0xe6,0xa5,0xcd,0xb2,0xf3,0xaa,0x4e,0xdb,0x70,
|
||||
0x0a,0x91,0x0f,0x70,0x99,0xfc,0x80,0xab,0x61,0x17,0xf6,0x0a,
|
||||
0xf6,0xa9,0x3c,0x49,0x60,0x04,0x22,0x89,0x55,0x88,0xff,0xc9,
|
||||
0x9d,0x24,0xc9,0x59,0xa7,0x91,0xd8,0x00,0x7b,0x8a,0x97,0x3b,
|
||||
0x29,0x09,0xf6,0xd9,0x9c,0x0a,0x6b,0x3f,0x93,0xfb,0x5e,0x92,
|
||||
0x40,0x8a,0x25,0x2e,0x02,0x72,0x9b,0x64,0x57,0xd2,0x2c,0x4b,
|
||||
0xbc,0x31,0xb7,0xac,0xda,0x95,0xf1,0x21,0xcd,0x23,0xa9,0xd8,
|
||||
0x28,0x28,0x99,0x6e,0x42,0xd3,0xc4,0x8b,0xf3,0x49,0xb6,0x8e,
|
||||
0x3e,0xd1,0x8a,0x25,0x74,0x1a,0x5a,0xbc,0x05,0x56,0xa7,0x67,
|
||||
0x63,0x09,0x63,0xa4,0x82,0xd7,0x13,0x23,0xbe,0x8e,0xaf,0x79,
|
||||
0x66,0xbe,0x8b,0x09,0x2d,0x4a,0x44,0x7c,0x42,0x95,0x26,0xfa,
|
||||
0x46,0xd6,0xf8,0xdb,0xc4,0xae,0x92,0xf4,0x97,0x53,0xcb,0x5c,
|
||||
0xfe,0x47,0x50,0xd6,0x61,0x9f,0x31,0xe3,0x66,0xe3,0x14,0x73,
|
||||
0x90,0x04,0x5e,0x44,0xfb,0x98,0xa4,0xf9,0xa2,0x4f,0xab,0x30,
|
||||
0x7f,0xa2,0xa2,0x3f,0x72,0xeb,0x67,0x44,0x7a,0x8e,0x67,0xb4,
|
||||
0x2b,0x3b,0x57,0x9a,0x38,0xee,0x6c,0x50,0x9d,0x8e,0xd8,0x87,
|
||||
0xca,0x4e,0x13,0x6d,0x94,0x6b,0xe0,0x3b,0x6f,0xcc,0x6c,0x05,
|
||||
0x46,0x80,0xef,0x44,0x67,0x66,0x52,0xf2,0x55,0xbd,0x2c,0x05,
|
||||
0xd4,0x55,0x4f,0x33,0x45,0x62,0x13,0xf4,0x2a,0xda,0x15,0xb1,
|
||||
0xcc,0xe2,0xcd,0xf3,0x08,0xce,0xac,0xcd,0xc0,0xd8,0x15,0x69,
|
||||
0x69,0x46,0x82,0x8c,0x5f,0x8b,0xde,0xcc,0xf3,0x5d,0x0a,0x8a,
|
||||
0xd6,0x2b,0x25,0x8c,0xd3,0x80,0x13,0x29,0xb8,0xd5,0xd5,0x66,
|
||||
0x6b,0x2e,0x3d,0xa5,0x7c,0x57,0xe2,0x79,0xba,0x0c,0xbf,0x55,
|
||||
0x29,0x5f,0xc5,0x1e,0x97,0x39,0xee,0x4a,0x72,0x31,0x2a,0xd9,
|
||||
0x52,0xca,0xde,0x26,0xb3,0xa5,0xa9,0x8f,0xa5,0x37,0xa7,0x27,
|
||||
0xe7,0xd4,0x7f,0x08,0xf3,0xa6,0x45,0x85,0x27,0x1d,0x5d,0xe5,
|
||||
0x8f,0x20,0xbf,0x38,0x24,0x19,0x6b,0x4e,0x5d,0x42,0x27,0xa7,
|
||||
0x32,0x86,0xb3,0xed,0xd6,0x1c,0x01,0x98,0xe1,0x48,0x05,0x3f,
|
||||
0x52,0xef,0x94,0xc8,0x99,0xe8,0xe1,0x08,0x29,0xd6,0x6e,0x94,
|
||||
0x24,0x19,0x65,0xe4,0x51,0xe5,0x6e,0xa4,0x35,0x22,0x19,0x0c,
|
||||
0x9e,0xa2,0x45,0x80,0x5a,0x58,0x11,0xcf,0xd4,0x5c,0x76,0xe7,
|
||||
0x57,0x94,0xb2,0x57,0xb3,0x82,0x4c,0x4d,0x0c,0x4b,0x52,0x89,
|
||||
0xe4,0x63,0x2a,0x1a,0x04,0x44,0x72,0x4d,0x5c,0x37,0xc4,0xf1,
|
||||
0x07,0x48,0x3b,0x45,0x27,0xde,0x1c,0x52,0x28,0x89,0x94,0x33,
|
||||
0x29,0x39,0x4b,0xdd,0x6e,0x89,0x63,0x92,0x9e,0x4e,0x4c,0xb2,
|
||||
0x28,0x89,0xdf,0x69,0x47,0x5c,0x3d,0xb1,0x8d,0x99,0x58,0x9a,
|
||||
0xea,0x4c,0xc7,0xe4,0xa2,0x6d,0x8d,0xf8,0x11,0x2f,0xd6,0x27,
|
||||
0xce,0xea,0x92,0x41,0x6e,0x6b,0x1c,0xf0,0x8c,0x24,0x15,0x35,
|
||||
0xba,0x78,0xb6,0x48,0xeb,0x91,0x8b,0xe3,0x84,0x75,0xf4,0x31,
|
||||
0x6d,0xca,0xf7,0xb9,0xb9,0x14,0x35,0x1a,0x8c,0x69,0x10,0x22,
|
||||
0x93,0x13,0xc9,0xa3,0x07,0x57,0xd3,0x14,0x14,0xec,0x76,0x94,
|
||||
0xe0,0x3b,0x54,0x86,0x55,0x5d,0x25,0xe3,0xe3,0xb5,0xdb,0x37,
|
||||
0x57,0x94,0xf0,0xca,0xd4,0x20,0xd7,0xc3,0x2b,0x62,0x7d,0x20,
|
||||
0x67,0x9c,0x04,0x60,0xcb,0xc4,0x24,0x4c,0xe2,0x10,0x9e,0x6a,
|
||||
0x1c,0xa2,0x1e,0x19,0xd4,0xab,0x2c,0x7b,0x90,0xde,0x8c,0x00,
|
||||
0x68,0x0e,0xe2,0xd6,0x3c,0x38,0x02,0xca,0x20,0x89,0x46,0x46,
|
||||
0x6c,0x86,0xde,0x01,0x81,0xa5,0x12,0xc6,0x4e,0x73,0xec,0x80,
|
||||
0xdc,0xfb,0xb1,0x54,0xb6,0x80,0xad,0xef,0x0c,0x09,0x2a,0x1c,
|
||||
0x06,0x39,0xa0,0x76,0x65,0xfa,0x65,0xa8,0xa7,0x1b,0x99,0x26,
|
||||
0x52,0x8c,0xb2,0x88,0xb4,0x86,0xa1,0xe2,0xd7,0x25,0x08,0xe9,
|
||||
0x46,0xd5,0x25,0xe4,0x59,0x51,0x3c,0xcb,0x49,0x3e,0x90,0xb4,
|
||||
0xfe,0x5e,0x63,0x9e,0x53,0x71,0x04,0xd6,0xb7,0xeb,0x35,0xd8,
|
||||
0x4f,0x6b,0xeb,0x33,0x9e,0xa0,0x68,0xc7,0xd2,0x56,0x14,0x6d,
|
||||
0x4a,0x7a,0xc2,0x38,0xaf,0xab,0x30,0x97,0xad,0x46,0x8e,0x13,
|
||||
0x19,0x4a,0x59,0x41,0x35,0xd5,0x98,0x96,0x1a,0x8b,0x6c,0x0a,
|
||||
0x2d,0xfd,0x60,0x84,0x59,0xfd,0x38,0x2e,0x1b,0xcd,0xd5,0x55,
|
||||
0x08,0xfa,0x70,0x35,0x4a,0xe7,0x15,0x35,0x74,0x9d,0x01,0x5c,
|
||||
0x13,0xa4,0x7c,0x15,0x50,0xa7,0xc4,0xc9,0x1f,0x71,0xb3,0xe2,
|
||||
0xfe,0x40,0x10,0xa4,0xb9,0x71,0xc9,0x60,0x60,0x92,0x02,0x3f,
|
||||
0xf3,0x70,0x48,0x46,0x52,0xb9,0x5e,0x0a,0x02,0xba,0x0e,0x5d,
|
||||
0x05,0x29,0x98,0x6f,0x27,0x21,0xc8,0xcd,0x39,0x50,0xf6,0xaf,
|
||||
0xc4,0xda,0xa2,0xaa,0xa7,0x10,0xf0,0xaa,0x1b,0x6c,0x95,0xd9,
|
||||
0xa4,0x21,0x9b,0xcc,0x62,0xa1,0x28,0x8f,0xa9,0xd4,0x26,0xbd,
|
||||
0x02,0x0f,0x29,0xc5,0x37,0x85,0x41,0x4d,0x2b,0x2f,0xd7,0xa2,
|
||||
0xa3,0xab,0x8c,0xe2,0x97,0x3c,0x9d,0x96,0x13,0xa7,0xa4,0xc2,
|
||||
0x93,0x96,0x8e,0x52,0xd2,0xc0,0x67,0x89,0xf1,0x01,0x32,0xeb,
|
||||
0xd7,0xaa,0x74,0x91,0x72,0x28,0x1c,0xad,0x71,0x90,0xe1,0xbd,
|
||||
0x0d,0xb2,0xeb,0x15,0xb8,0xd2,0xd8,0xac,0x37,0xd7,0xf7,0xa2,
|
||||
0x38,0xa4,0x28,0x52,0xc3,0xc6,0x1d,0x2d,0xc5,0xf9,0x5e,0xd3,
|
||||
0xf0,0xff,0x0a,0x7c,0xbb,0x99,0x5d,0x85,0x46,0xd7,0x01,0x33,
|
||||
0x0b,0x5d,0xf4,0x62,0x8c,0xe0,0xaf,0x87,0xf3,0x6d,0x7c,0x90,
|
||||
0xaf,0xcb,0x2b,0x2a,0x3e,0x91,0x69,0xc8,0x53,0x19,0x57,0x9d,
|
||||
0x39,0x38,0x11,0xe0,0xb0,0x9b,0xb3,0x26,0x28,0xdc,0xd1,0x40,
|
||||
0x95,0xdf,0xad,0x04,0x79,0xdc,0x5a,0x6a,0x8a,0xbf,0x7a,0x39,
|
||||
0x35,0xb8,0x51,0x75,0x56,0x5c,0x50,0x6b,0x01,0xef,0x06,0x61,
|
||||
0xfc,0xc6,0x8f,0x26,0xd6,0xb9,0x9e,0x80,0xd5,0x65,0xb2,0xd8,
|
||||
0x8e,0xb0,0x9a,0xac,0x4a,0xc4,0x15,0x92,0x52,0x32,0xd0,0x9c,
|
||||
0x9e,0xe0,0x04,0xb1,0x64,0x90,0xae,0xfb,0xf3,0x04,0xeb,0xfe,
|
||||
0xda,0x95,0x78,0x22,0x53,0xfb,0xa0,0x1a,0x3f,0x21,0x3f,0x97,
|
||||
0xcc,0xa5,0x4c,0x28,0x45,0x8f,0x4d,0x82,0x91,0x37,0x61,0x98,
|
||||
0x31,0x97,0x20,0x66,0xed,0x40,0xbf,0xda,0x5a,0xf9,0x2c,0x12,
|
||||
0xed,0x50,0xc6,0x41,0xb2,0xd6,0x96,0xd4,0x66,0xac,0xdd,0xa3,
|
||||
0xe0,0x23,0x2b,0xad,0xed,0xe4,0x47,0x9b,0x0c,0x85,0x8d,0x66,
|
||||
0xec,0x25,0x6f,0x7c,0x2a,0xe3,0x66,0xc6,0xcb,0x8e,0x5c,0x2f,
|
||||
0xe2,0x12,0xac,0x41,0xb5,0xd9,0xf1,0x53,0x6b,0x74,0x89,0x4c,
|
||||
0x02,0xa1,0x99,0x1d,0x30,0xaf,0x93,0x66,0xed,0x2b,0x72,0xcd,
|
||||
0x52,0x49,0x50,0xb7,0x64,0xd1,0x05,0xee,0xe9,0xa4,0x22,0xea,
|
||||
0x92,0x54,0x53,0xca,0x7e,0x6c,0xd0,0x1f,0x6b,0x41,0x3b,0x36,
|
||||
0x58,0xca,0x97,0x3b,0xfa,0x95,0x14,0x89,0xf2,0x15,0x57,0x54,
|
||||
0x18,0xf5,0xd5,0x08,0x68,0xeb,0x5f,0x84,0xb2,0x21,0x12,0x0a,
|
||||
0x14,0x08,0xdf,0x04,0xa5,0xa3,0xb0,0xb8,0x6b,0x01,0xa0,0xde,
|
||||
0xda,0xb5,0x92,0x82,0x87,0xa9,0x5a,0x77,0x53,0xe2,0xf6,0x30,
|
||||
0x21,0x97,0x40,0x10,0x15,0x6b,0xe4,0x39,0xb3,0x62,0x22,0x1a,
|
||||
0x19,0x0d,0xe7,0x1d,0xd3,0xec,0x71,0xcc,0x3b,0xd5,0x9c,0x34,
|
||||
0xb2,0x21,0xef,0x84,0x7d,0x10,0xbc,0x4c,0x1f,0x84,0x98,0x5f,
|
||||
0x3c,0xba,0x0d,0x02,0xfe,0x3c,0xf0,0xfb,0x26,0x14,0x88,0x2c,
|
||||
0x24,0xf1,0x8d,0xa0,0xef,0x4a,0x46,0x6e,0x2a,0xf4,0x5d,0xe1,
|
||||
0xae,0x3c,0x0f,0xd6,0xb5,0x19,0xf6,0x71,0xe1,0x5f,0x6f,0x52,
|
||||
0x4e,0x1f,0x83,0x44,0xdf,0xb0,0xd1,0x56,0x9e,0xfc,0xe6,0xf5,
|
||||
0x24,0x89,0x9b,0x19,0x00,0xb5,0xb4,0x2e,0x4f,0x56,0x1b,0xf7,
|
||||
0x0b,0x28,0x46,0x36,0x5e,0x26,0x9f,0x3b,0x25,0x3f,0x9f,0x8b,
|
||||
0x78,0xf6,0x4f,0x84,0x6f,0x66,0x0d,0x62,0x16,0xc7,0x4c,0xb1,
|
||||
0x4f,0x98,0xf3,0xf2,0x57,0x2f,0x2a,0xd5,0xb0,0xf0,0x62,0xb5,
|
||||
0xae,0x44,0x66,0xb0,0xba,0x23,0xab,0x25,0xa8,0xad,0x9a,0xca,
|
||||
0xd0,0x88,0xcf,0x93,0x38,0x30,0x8e,0x0a,0x91,0x1a,0x21,0xdd,
|
||||
0x24,0x3c,0x5a,0x03,0x35,0x5e,0xc9,0xca,0xfe,0x4e,0xe6,0xce,
|
||||
0x85,0x08,0x43,0xe1,0x0d,0x33,0xa2,0xbf,0x5b,0x3b,0xb6,0xbe,
|
||||
0x3b,0x2b,0xf1,0x79,0xd1,0x0b,0x59,0xbc,0x91,0x27,0xe9,0xb9,
|
||||
0x11,0x76,0x46,0xec,0xa3,0x44,0x75,0x5a,0x06,0x62,0x5d,0xdf,
|
||||
0x8e,0x13,0x51,0x59,0xd5,0x03,0xcf,0xc8,0x6f,0x56,0x76,0xab,
|
||||
0xd3,0x3b,0x94,0x57,0xa1,0x8e,0xce,0xb5,0x8f,0x4b,0xd1,0x98,
|
||||
0x55,0x2b,0xac,0xe2,0x85,0x92,0x92,0x22,0xab,0x70,0xa4,0xb5,
|
||||
0xbc,0x54,0x8d,0xbc,0x8f,0x97,0xad,0xe6,0x7b,0xdb,0xfc,0x3b,
|
||||
0x45,0x75,0xcc,0xa0,0xe8,0x63,0x72,0x25,0x77,0x49,0xa0,0x2b,
|
||||
0x64,0xdd,0x6a,0x18,0x69,0x9e,0xf6,0x99,0x22,0xfb,0xd6,0xf8,
|
||||
0xed,0xa5,0x40,0x93,0x1f,0xdb,0x95,0x6b,0xcb,0x95,0x7d,0x44,
|
||||
0x61,0xe7,0x0e,0x2f,0xeb,0x23,0xea,0xf6,0xed,0xa0,0x72,0x71,
|
||||
0x9e,0x5e,0x2e,0xae,0x11,0x6b,0x42,0xc9,0x58,0x27,0xa7,0xde,
|
||||
0x92,0x5e,0x27,0x1a,0x88,0x3a,0x3d,0x97,0x3f,0xf2,0xdb,0x55,
|
||||
0xed,0x60,0xa5,0x1a,0x46,0x99,0xb7,0x27,0x9a,0x6e,0xa4,0xbb,
|
||||
0xa7,0xb5,0x56,0x61,0x82,0x34,0x1e,0xc6,0x8d,0x86,0xd9,0xaa,
|
||||
0x91,0x30,0xd6,0x7a,0xaa,0x01,0x77,0x9d,0x81,0x46,0x0d,0x8f,
|
||||
0x28,0x02,0x44,0xc5,0xc3,0x4a,0x4c,0x2c,0xb1,0xa0,0x50,0xf3,
|
||||
0x92,0x46,0x98,0x89,0x40,0xad,0x5e,0xdd,0x0e,0xf8,0xf5,0x6c,
|
||||
0x4e,0x6a,0x6b,0xa6,0x52,0x35,0xbd,0x96,0xdf,0x89,0xb5,0x9e,
|
||||
0x35,0x51,0x7e,0xff,0x48,0xe1,0xea,0x4f,0xd9,0xda,0x79,0xd1,
|
||||
0x5a,0x20,0x97,0x53,0x1f,0x28,0x58,0xe5,0x0a,0x69,0xbe,0x20,
|
||||
0xae,0x62,0x46,0xd4,0x36,0x79,0x23,0x9d,0x6b,0x75,0x2d,0x8e,
|
||||
0x0a,0x10,0x36,0xd1,0xa7,0x91,0x64,0x9d,0x20,0x20,0x41,0xc5,
|
||||
0x9f,0x98,0xea,0xc4,0x32,0x8b,0xbc,0x31,0xc6,0xfd,0x1c,0xa4,
|
||||
0x3d,0x2c,0x64,0xba,0x81,0xee,0xb1,0x08,0x5e,0x26,0xa1,0x21,
|
||||
0xeb,0xec,0x50,0x0c,0xd7,0x48,0x66,0x6d,0xf3,0x4e,0x49,0xae,
|
||||
0x95,0xb8,0x02,0x67,0x52,0xc2,0xdc,0xba,0xf9,0xcf,0xef,0x5f,
|
||||
0x9a,0xcb,0x83,0x25,0xce,0x7a,0x34,0x56,0x8f,0xca,0xde,0x57,
|
||||
0xe4,0xc5,0x24,0xca,0x4c,0x96,0xd6,0x33,0x67,0x1a,0xc8,0x8d,
|
||||
0x69,0x0d,0xac,0xc3,0xeb,0x01,0xab,0xe2,0x33,0x39,0xdc,0x38,
|
||||
0x3b,0x1e,0x24,0xb7,0xee,0x28,0xb7,0x57,0x22,0xaf,0xf7,0x21,
|
||||
0x57,0x6c,0x11,0xfd,0xc8,0x6c,0x85,0xfc,0x4c,0x6e,0x27,0x3c,
|
||||
0x81,0xbd,0x40,0x29,0xa2,0xb8,0x19,0x99,0x40,0x8c,0x92,0xea,
|
||||
0xc0,0x9f,0x67,0x96,0xb8,0xf6,0x8a,0xe4,0x37,0xca,0x4b,0xe1,
|
||||
0x56,0xbf,0x92,0xe6,0xb2,0x58,0x86,0x83,0xc9,0x3d,0x79,0x92,
|
||||
0x86,0x00,0x18,0x72,0xee,0xe8,0xeb,0x88,0x20,0xa3,0x42,0xea,
|
||||
0x88,0x42,0x52,0x27,0x96,0x54,0x3d,0xfb,0x7e,0x07,0xd4,0x54,
|
||||
0x7d,0x2c,0xa5,0xfc,0xa5,0xcb,0x99,0x9d,0x25,0xca,0xdf,0x13,
|
||||
0x56,0x9d,0x10,0x35,0x11,0x63,0xa0,0x12,0x94,0xc8,0xac,0x03,
|
||||
0xd6,0x59,0x4b,0x28,0xed,0x11,0xc3,0x8b,0x9e,0x94,0x24,0xc7,
|
||||
0x2a,0xb2,0x99,0x8a,0x4b,0xf0,0x3b,0xa6,0x56,0x45,0x2f,0x76,
|
||||
0xbd,0xb2,0xa4,0xc5,0xef,0xed,0x6e,0xf1,0xfb,0x15,0x65,0xac,
|
||||
0x1d,0xde,0x3e,0x93,0x4d,0xb1,0x80,0x7f,0x23,0x07,0xe1,0xf7,
|
||||
0x2d,0xb2,0x6e,0x1f,0x0a,0x8c,0x57,0x8a,0x38,0x46,0x5a,0x20,
|
||||
0x9b,0x24,0xb5,0x97,0x05,0x79,0x85,0x6b,0x7c,0x31,0x49,0x5b,
|
||||
0x48,0xc8,0x9d,0x87,0x48,0xd1,0xee,0xcf,0xc8,0x42,0xb9,0x44,
|
||||
0x4c,0xeb,0x87,0xbc,0xfc,0xfa,0xa1,0x3c,0xde,0xf1,0xd8,0x2a,
|
||||
0x85,0xdc,0x0c,0x3f,0x86,0x7b,0xaa,0x41,0xcc,0xf8,0xbe,0x6c,
|
||||
0xae,0xa4,0x57,0x92,0x3b,0x61,0x67,0x7c,0x81,0x89,0x97,0x91,
|
||||
0x78,0xb5,0xc8,0x99,0x9f,0xcd,0xab,0x90,0x5d,0x84,0x92,0xb8,
|
||||
0x8b,0x71,0x6f,0x6f,0x18,0x7f,0xf8,0x55,0x2b,0xd7,0x88,0x8a,
|
||||
0x7e,0x21,0xfc,0x64,0x59,0x1e,0x50,0x1f,0xa8,0x03,0x03,0x51,
|
||||
0x7f,0x84,0x42,0x1d,0x72,0x91,0x27,0xd9,0x0b,0x1c,0x39,0x58,
|
||||
0x10,0xd8,0xfa,0xaa,0x7c,0x01,0x54,0xcb,0xbd,0x48,0xd8,0x54,
|
||||
0x61,0x5c,0x58,0x83,0xad,0xed,0x93,0xf5,0x35,0xb3,0x39,0xbd,
|
||||
0xcc,0xb8,0x99,0xfe,0x34,0x7a,0x4a,0xb6,0x89,0x11,0xc6,0xa6,
|
||||
0xe2,0xb5,0x7f,0x05,0xf5,0x35,0xd4,0x73,0xc8,0xda,0xf0,0x5f,
|
||||
0x47,0xef,0x2e,0x47,0x39,0x0c,0x48,0xaf,0x67,0xd4,0x80,0x29,
|
||||
0x18,0x97,0x5d,0x27,0x4c,0x49,0x0d,0xfc,0x78,0x00,0xd5,0xa5,
|
||||
0x2d,0x43,0x32,0xfa,0xa4,0x11,0x34,0xab,0x26,0x0b,0x61,0x35,
|
||||
0x80,0xd4,0xa3,0x1e,0x98,0xc2,0x4a,0xd9,0x38,0x0d,0x80,0x35,
|
||||
0x75,0x61,0xc7,0x11,0xd6,0x78,0xed,0xad,0x46,0x5c,0xa8,0x21,
|
||||
0xb4,0x04,0x2d,0x3a,0x82,0x16,0x58,0x75,0xe8,0x3b,0x37,0x67,
|
||||
0xbd,0x76,0x9d,0x7c,0x0b,0x86,0xdc,0xab,0xa7,0xef,0xa6,0x19,
|
||||
0xc6,0x1e,0xb8,0xb5,0xe8,0xbc,0xd5,0xad,0xae,0x06,0xf4,0xb4,
|
||||
0x76,0x18,0xf3,0xe8,0xc8,0x50,0xa4,0xc9,0xb2,0xfe,0x90,0xb1,
|
||||
0xc9,0x1f,0xe6,0x92,0xaa,0x9e,0x4e,0x5f,0x68,0x93,0xce,0x81,
|
||||
0x05,0xd6,0xa2,0x17,0x75,0x11,0x8c,0xcd,0x55,0xed,0x16,0x2a,
|
||||
0x71,0xff,0x76,0x4d,0x39,0x44,0xe9,0x47,0xdd,0xce,0x75,0xbc,
|
||||
0x2c,0x59,0x95,0xcc,0x82,0x32,0x05,0xea,0x9a,0x6a,0x24,0x84,
|
||||
0xcc,0x0c,0x2e,0x61,0xb6,0xcf,0x04,0xae,0x50,0x57,0x36,0x1c,
|
||||
0xb2,0xb8,0x3e,0x05,0x0a,0x46,0xbf,0xbd,0x52,0x6a,0x24,0xe5,
|
||||
0x38,0x99,0x31,0x01,0x8c,0x86,0xf4,0x73,0x3c,0x7d,0xfd,0xd8,
|
||||
0x48,0xbe,0x94,0x83,0x06,0xfa,0x70,0x4d,0x0a,0xfb,0xf6,0x15,
|
||||
0xf2,0x6a,0x4e,0x32,0x33,0xac,0x90,0xd7,0x93,0x20,0x93,0xd6,
|
||||
0x8b,0x5d,0x75,0x15,0xf4,0x2b,0x8f,0x2b,0x33,0x43,0xf2,0xc6,
|
||||
0x65,0xa5,0x01,0x3c,0xb3,0x91,0x01,0xb4,0x29,0x8c,0x6d,0x9d,
|
||||
0x98,0xc3,0x15,0x30,0x57,0x83,0x1c,0xec,0xa9,0xe2,0x4f,0x3d,
|
||||
0x37,0xaf,0x3c,0x3a,0xf1,0xd0,0x54,0x52,0xf2,0xdd,0xda,0xf9,
|
||||
0xda,0xdd,0xfa,0xdd,0x7d,0x8d,0xba,0xc7,0x26,0x01,0x7e,0x4e,
|
||||
0xeb,0x58,0xd0,0xd6,0xc8,0x33,0x8c,0xec,0xb1,0xd0,0xff,0x16,
|
||||
0x5a,0xd6,0x8d,0xec,0xc0,0x47,0x67,0x8d,0xb4,0xbb,0xf0,0x19,
|
||||
0x98,0xde,0x6c,0x3d,0xba,0x22,0x7e,0x94,0xfc,0xdf,0xbc,0x5e,
|
||||
0x7c,0xfc,0x16,0x42,0x6c,0xa3,0x21,0x0d,0xfd,0x07,0xda,0x30,
|
||||
0xe4,0xfa,0xbb,0x32,0x18,0x18,0x3f,0xb7,0x71,0x40,0x18,0xf8,
|
||||
0xed,0xaa,0xfe,0xad,0x5a,0x7f,0xc4,0xaa,0x0e,0x50,0xea,0x80,
|
||||
0x19,0xc0,0xa5,0xea,0xcb,0xe6,0xc1,0xc5,0xfa,0xb0,0x0d,0x85,
|
||||
0xab,0x5d,0xd9,0x77,0x55,0xf2,0x5b,0x73,0x62,0xde,0xea,0xf4,
|
||||
0x01,0x0d,0x9e,0x93,0xfe,0x56,0x56,0xa7,0xa0,0x6a,0x45,0xb8,
|
||||
0x7a,0x4f,0x61,0xed,0x5e,0x1a,0x0f,0x76,0x0c,0xfd,0x63,0x5e,
|
||||
0x9f,0x23,0x9e,0xa4,0x95,0x49,0x66,0x32,0x0e,0x9a,0x78,0x86,
|
||||
0x49,0xc4,0x97,0x12,0xb4,0xb4,0x20,0x26,0xb2,0x64,0xb6,0xa1,
|
||||
0x7b,0x58,0x4f,0xcc,0xb1,0x9e,0x9e,0x82,0x28,0xa4,0x8d,0x62,
|
||||
0x4b,0x41,0xed,0xa8,0xa3,0x71,0xdc,0xb1,0x5e,0xb8,0x12,0x5f,
|
||||
0x6a,0xbc,0x20,0x6b,0x50,0xec,0xb1,0x6e,0xda,0xc9,0xfb,0xa5,
|
||||
0x8a,0xe0,0x34,0x8a,0x1d,0x9b,0xc4,0xe3,0xea,0x82,0x0f,0x34,
|
||||
0x61,0x03,0x4d,0xe6,0x9c,0xa4,0x90,0x83,0x51,0xe2,0x48,0xb6,
|
||||
0x3e,0x36,0xe2,0x3e,0x90,0x16,0xc8,0xaa,0x39,0x33,0x1a,0x35,
|
||||
0x9f,0x9d,0x1a,0x1d,0x7c,0xb8,0xf5,0x85,0x5e,0x26,0xdd,0x45,
|
||||
0x75,0x9e,0xd0,0xaa,0x2d,0x9c,0x11,0xf6,0x8a,0x73,0x3c,0x53,
|
||||
0xfb,0xda,0xad,0x33,0xc2,0x99,0x57,0x19,0x2a,0xf8,0x15,0x40,
|
||||
0xc9,0xef,0x55,0x44,0xc9,0x2d,0x07,0x3c,0xf3,0x87,0x41,0xcd,
|
||||
0x23,0xeb,0xd9,0x9b,0xf5,0xb7,0x4b,0x4a,0x72,0x44,0x3d,0xee,
|
||||
0x1c,0xd0,0x91,0x0a,0x26,0xb5,0x9b,0x85,0x06,0xc0,0x41,0x44,
|
||||
0x07,0x1a,0x05,0x89,0x61,0x2f,0x39,0x4e,0xe4,0xc0,0x94,0x32,
|
||||
0x69,0x34,0x21,0x0f,0x26,0x75,0xa8,0xea,0x88,0x87,0x35,0x10,
|
||||
0x32,0xb2,0x1b,0x46,0x3e,0x6c,0x3a,0x34,0xd3,0xfc,0x8d,0x42,
|
||||
0xd4,0x28,0x98,0xf2,0xc1,0xb1,0x4d,0xe8,0x64,0x12,0x77,0x2e,
|
||||
0x35,0x68,0x4e,0xa1,0x34,0x1f,0x90,0x33,0xb1,0x3c,0x6d,0xeb,
|
||||
0x01,0xdb,0xf5,0xfa,0xeb,0x85,0xee,0x13,0xaf,0x18,0x52,0xfd,
|
||||
0x8d,0x15,0x79,0x0d,0x69,0xd5,0x23,0x96,0x06,0x35,0x6a,0xc5,
|
||||
0x50,0xa8,0xf7,0x26,0x2b,0xf6,0x1f,0xd1,0xee,0x96,0x99,0xf9,
|
||||
0x2d,0x66,0x6e,0xe7,0xcc,0x9a,0xe2,0xd2,0xc1,0x06,0xea,0x23,
|
||||
0xe3,0xbe,0x93,0xb5,0x0c,0x14,0x54,0xef,0x49,0x6d,0x31,0x6e,
|
||||
0xaa,0x93,0xec,0x7a,0x61,0x49,0x06,0xd9,0x40,0x60,0x1a,0xa5,
|
||||
0x93,0xea,0x82,0xa8,0xaa,0x04,0x94,0x11,0x8d,0xcc,0xe5,0x76,
|
||||
0x1d,0x7d,0x4e,0xe5,0xe0,0xd8,0xba,0xb0,0xb4,0x48,0x7a,0x1c,
|
||||
0x66,0x66,0x8a,0xa8,0xbb,0x61,0xb6,0x45,0xa5,0x68,0x10,0xb9,
|
||||
0xf7,0xa3,0xb8,0x59,0xa9,0x23,0x66,0xce,0x0d,0x93,0x3e,0x8e,
|
||||
0xd2,0xfa,0x4c,0x96,0xeb,0x64,0x77,0xae,0xf2,0x17,0x09,0xc9,
|
||||
0xe0,0xf5,0xc4,0xf0,0x96,0x14,0xf0,0xcb,0xbd,0x65,0xb5,0x91,
|
||||
0x36,0x93,0xcb,0x89,0x84,0xe9,0x76,0x19,0xa6,0x3b,0xae,0xa5,
|
||||
0x0b,0x3e,0x45,0x2d,0x86,0x0d,0xd6,0x28,0x91,0xbe,0xbc,0x96,
|
||||
0x8c,0x2c,0x49,0x32,0xc1,0xaa,0xbe,0x7d,0x9a,0x1b,0xad,0xf2,
|
||||
0x5c,0x4c,0x71,0x8b,0x58,0x95,0x85,0xae,0x7a,0x6b,0xb1,0xa5,
|
||||
0xfa,0x4b,0x85,0x3e,0x35,0xf0,0x72,0xfa,0x4d,0xaa,0x4b,0x7b,
|
||||
0xdd,0x75,0xe4,0x85,0x3a,0xc6,0x4e,0xf8,0x4e,0x8d,0x1a,0xbd,
|
||||
0xc1,0x1a,0xe9,0x3c,0x1d,0xa5,0xf0,0x3b,0xdb,0xfc,0xde,0xf5,
|
||||
0xe2,0xe9,0xa1,0x02,0x49,0x03,0xe7,0x85,0x26,0x34,0xe4,0xbc,
|
||||
0x50,0x83,0x47,0x95,0x36,0x9a,0xeb,0x85,0x4b,0x75,0xce,0x0b,
|
||||
0x05,0x10,0x94,0x55,0x6c,0xb0,0xfe,0x8d,0x67,0x47,0x83,0xa8,
|
||||
0x92,0x28,0xea,0x41,0x92,0xae,0x41,0xb2,0x98,0x3b,0x05,0x3f,
|
||||
0x59,0xec,0xcb,0x78,0x8d,0x35,0xe1,0x94,0xbf,0xc5,0xeb,0x33,
|
||||
0x51,0x10,0xfc,0x56,0x4c,0x81,0xf3,0xfb,0x6c,0xf1,0xe7,0x2d,
|
||||
0xe2,0xf7,0xcb,0x81,0x69,0xe8,0x10,0xaf,0xb9,0x89,0x3f,0xa0,
|
||||
0x9d,0xd9,0x26,0xd7,0x89,0x6b,0xca,0x43,0xc3,0x18,0x6d,0xd4,
|
||||
0x33,0x4d,0xa9,0x0d,0xbe,0x1e,0xdf,0x6a,0xca,0x44,0xc3,0x18,
|
||||
0x7a,0x28,0x13,0x1b,0x09,0x41,0x5d,0x32,0xd1,0x1c,0x8a,0x3c,
|
||||
0xad,0xaa,0x1f,0x49,0x32,0x97,0x21,0xa6,0xbc,0xa4,0x04,0x82,
|
||||
0xad,0x31,0xfe,0xa8,0xe7,0xbf,0x56,0x1c,0xba,0x6e,0xae,0x12,
|
||||
0xd7,0x35,0x55,0x75,0x5a,0x84,0xea,0x39,0x8d,0x94,0x1d,0x5b,
|
||||
0xd3,0xf9,0x5d,0xe4,0x7b,0xf4,0x72,0x07,0xf5,0xe4,0x12,0xea,
|
||||
0xca,0x2b,0x90,0x84,0x8d,0xe9,0x6a,0xd4,0x73,0xab,0x91,0x74,
|
||||
0x55,0xe6,0x5a,0x06,0x5e,0x6d,0xaa,0x06,0x95,0x9c,0xc8,0x82,
|
||||
0xf8,0xd1,0x07,0x3b,0xa3,0x3d,0x04,0x33,0xe1,0xf1,0x68,0xdf,
|
||||
0x82,0x36,0x38,0x16,0xed,0xdb,0xc4,0x79,0x87,0xd8,0x2f,0x84,
|
||||
0x5d,0x39,0x82,0x47,0x53,0x70,0x1e,0x45,0x47,0x1d,0xf8,0x1d,
|
||||
0x14,0x5d,0x73,0x12,0xb8,0xd1,0xbe,0x85,0x31,0xbc,0x30,0xda,
|
||||
0xb7,0xb1,0x74,0x5b,0x11,0xed,0x3b,0xc4,0x67,0x0a,0x30,0x01,
|
||||
0x6e,0x8b,0xf6,0x9b,0x82,0xf3,0x36,0x20,0xa7,0x25,0x1a,0x67,
|
||||
0xb8,0x1f,0x8e,0x33,0xdc,0x0f,0xc7,0x19,0xee,0xdb,0x30,0x1f,
|
||||
0x1e,0x89,0xf6,0x1d,0xe2,0x33,0xe1,0x38,0xc3,0xfd,0x70,0x9c,
|
||||
0xab,0x61,0x00,0xff,0xad,0xc1,0xd4,0x0d,0x5f,0x5d,0x58,0xbb,
|
||||
0xff,0x42,0xcf,0x9e,0xd3,0x47,0xcf,0x8c,0x0e,0x9f,0xe8,0xd9,
|
||||
0x71,0xfa,0xe8,0xf1,0xe3,0x23,0xa7,0xef,0x1d,0x39,0x7c,0xf6,
|
||||
0xd8,0xf0,0xe9,0x3d,0x7b,0xf6,0xf5,0xec,0x3a,0x7d,0xf2,0xf0,
|
||||
0xe1,0x0b,0xdb,0x8e,0x8d,0x0c,0x9f,0xd8,0xb3,0x67,0xf5,0xc0,
|
||||
0xc0,0x9a,0x55,0xf8,0xdf,0x5d,0x0b,0xfb,0xe1,0x02,0xf4,0xc0,
|
||||
0x1e,0x38,0x0d,0x47,0xe1,0x0c,0x8c,0xc2,0x30,0x9c,0xc0,0xc7,
|
||||
0x3b,0x82,0xe3,0xe3,0xf8,0x6f,0x04,0xef,0xdd,0x8b,0x5f,0x0f,
|
||||
0xc3,0x59,0x3c,0xca,0x61,0x7c,0xb4,0x07,0xff,0xed,0xc3,0x9f,
|
||||
0xd9,0x85,0xf7,0x4f,0xe2,0xf3,0x87,0xf1,0x15,0xb6,0xe1,0xf7,
|
||||
0x46,0x82,0xef,0xfa,0xef,0xfa,0x78,0x8a,0x1f,0x5d,0x01,0x06,
|
||||
0x99,0x07,0x42,0xc1,0x8b,0x85,0x6c,0xe4,0xa0,0x02,0x6a,0x42,
|
||||
0x45,0xd4,0x8c,0x5a,0xd0,0x04,0x34,0x11,0xb5,0xa2,0x49,0xa8,
|
||||
0x0d,0x4d,0x46,0xed,0x68,0x0a,0xea,0x40,0x9d,0xa8,0x0b,0x75,
|
||||
0xa3,0xa9,0x68,0x1a,0x9a,0x8e,0x66,0xa0,0x99,0x68,0x16,0x9a,
|
||||
0x8d,0xe6,0xa0,0xb9,0x68,0x1e,0xea,0x09,0xa6,0x75,0x01,0x63,
|
||||
0xa3,0x08,0xcd,0xd0,0x82,0x71,0x3e,0x11,0x5a,0x31,0xb6,0xdb,
|
||||
0x30,0xff,0xb7,0x63,0xca,0x74,0xe0,0x59,0xd0,0x85,0xe7,0xc6,
|
||||
0x54,0x3c,0x17,0xa6,0xc3,0x0c,0x8c,0xb3,0x59,0x30,0x1b,0xe6,
|
||||
0xc0,0x5c,0x3c,0x2f,0x7a,0xa0,0x17,0xe3,0x79,0x01,0xa6,0x47,
|
||||
0x3f,0xa6,0xe6,0x22,0x58,0x0c,0x4b,0x60,0x29,0x9e,0x29,0xcb,
|
||||
0x31,0x3d,0x57,0x06,0x18,0x75,0x31,0x7e,0x4b,0x18,0xaf,0x6b,
|
||||
0x61,0x10,0xcf,0x9d,0x32,0x54,0x60,0x3d,0x9e,0x41,0x1b,0x61,
|
||||
0x13,0xa6,0xec,0x66,0x18,0x82,0x2d,0xb0,0x15,0xc3,0x7c,0x3b,
|
||||
0x6c,0x87,0x3b,0x30,0xae,0x76,0xc2,0xc7,0xe0,0x4e,0x3c,0xb3,
|
||||
0xee,0x82,0xdf,0x84,0xbb,0xf1,0xfc,0xda,0x05,0xbf,0x85,0x71,
|
||||
0xb6,0x1b,0x63,0xe2,0xe3,0xb0,0x17,0xee,0xc3,0xd8,0xfa,0x04,
|
||||
0xfc,0x36,0x7c,0x12,0xee,0x87,0xdf,0x81,0x07,0xe0,0x41,0x78,
|
||||
0x08,0x86,0x51,0x2f,0x9a,0x8f,0x16,0xa0,0x3e,0xd4,0x8f,0x16,
|
||||
0xa2,0x45,0x68,0x31,0x5a,0x82,0x96,0xa2,0x65,0x68,0x39,0x5a,
|
||||
0x81,0x56,0xa2,0x55,0x68,0x00,0xb9,0x68,0x35,0x2a,0xa1,0x35,
|
||||
0x68,0x2d,0x1a,0x44,0xeb,0x50,0x19,0x55,0xd0,0x7a,0xb4,0x01,
|
||||
0x6d,0x44,0x9b,0xd0,0x6d,0x68,0x33,0x1a,0x42,0x5b,0xe0,0x2a,
|
||||
0xfc,0x19,0x3c,0x09,0x9f,0x87,0xef,0xc2,0x65,0x78,0x17,0x9e,
|
||||
0x82,0x67,0xe0,0x4b,0xf0,0x27,0xf0,0x17,0xf0,0x0d,0xf8,0x05,
|
||||
0x5c,0x84,0xb7,0xe1,0x09,0xf8,0x03,0xf8,0x1f,0xf8,0x5f,0xf8,
|
||||
0x32,0xfc,0x21,0x3c,0x0d,0xdf,0x83,0x9f,0xc0,0x7f,0xc3,0x0b,
|
||||
0xf0,0x12,0xfc,0x12,0x3e,0x80,0x5f,0xc1,0x8b,0xf0,0x97,0xf0,
|
||||
0x4f,0xf0,0x8f,0x70,0x0d,0x73,0xc0,0x01,0xb8,0x04,0x07,0xe1,
|
||||
0x5f,0x30,0x05,0x6f,0xc0,0x3f,0xc3,0xbf,0xc1,0x6b,0xf0,0xaf,
|
||||
0xf0,0x7d,0xf8,0x19,0x1c,0x82,0x1f,0xc2,0xeb,0xf0,0xef,0xf0,
|
||||
0x4d,0x4c,0xe3,0xf7,0xe1,0xab,0xf0,0x23,0x78,0x03,0xde,0x84,
|
||||
0x23,0xf0,0x73,0xf8,0x2f,0xf8,0x22,0x7c,0x0a,0x73,0xc8,0xa7,
|
||||
0x31,0x87,0x1c,0xc3,0x54,0xff,0x3a,0xe6,0x84,0xdf,0x85,0x53,
|
||||
0x98,0x23,0xce,0x60,0x3e,0x19,0x85,0x73,0xf0,0x30,0xdc,0x84,
|
||||
0xf3,0x98,0x97,0x2f,0xc0,0x67,0xe0,0xf7,0xe0,0xb3,0x70,0x1d,
|
||||
0xfe,0x14,0x3e,0x07,0x8f,0x62,0x1d,0xfa,0x18,0xbc,0x07,0xb7,
|
||||
0xe0,0xdb,0x6d,0x67,0x4f,0x1c,0x3d,0x70,0xf2,0xe0,0xc8,0x82,
|
||||
0x81,0xf3,0x03,0x03,0x03,0x2e,0x7d,0xb8,0x9a,0x3e,0x2c,0xd1,
|
||||
0x87,0x6b,0xe8,0xc3,0xb5,0xf4,0xe1,0x20,0x7d,0xb8,0x8e,0x3e,
|
||||
0x2c,0xd3,0x87,0x15,0xfa,0x70,0x98,0x3e,0xdc,0x4f,0x1f,0x1e,
|
||||
0xa0,0x0f,0x0f,0xd2,0x87,0x23,0xf4,0xe1,0x21,0xea,0xd0,0x1d,
|
||||
0xa0,0x0f,0x69,0x78,0x5d,0x1a,0x5e,0x97,0x86,0xd7,0xa5,0xe1,
|
||||
0x75,0x69,0x78,0x5d,0x1a,0x5e,0x97,0x86,0xd7,0xa5,0xe1,0x75,
|
||||
0x69,0x78,0x5d,0x1a,0x5e,0x97,0x86,0xd7,0xa5,0xe1,0x75,0x69,
|
||||
0x78,0x5d,0x1a,0x5e,0xf7,0x50,0xd3,0xc1,0x91,0x63,0x23,0xa3,
|
||||
0x23,0xce,0xf6,0xb3,0xa7,0x4f,0x52,0x6f,0x95,0x69,0x60,0xcb,
|
||||
0x34,0xb0,0x65,0x1a,0xd8,0x32,0x0d,0x6c,0x99,0x06,0xb6,0x4c,
|
||||
0x03,0x5b,0xa6,0x81,0x2d,0xd3,0xc0,0x96,0x69,0x60,0xcb,0x34,
|
||||
0xb0,0x65,0x1a,0xd8,0x32,0x0d,0x6c,0x99,0x06,0xb6,0x4c,0x03,
|
||||
0x5b,0xa6,0x89,0x5b,0xa1,0x89,0x5b,0xa1,0xe1,0xad,0xd0,0xf0,
|
||||
0x56,0x68,0x78,0x2b,0x34,0xbc,0x15,0x1a,0xde,0x0a,0x0d,0x6f,
|
||||
0x85,0x86,0xb7,0x42,0xc3,0x5b,0xa1,0xe1,0xad,0xd0,0xf0,0x56,
|
||||
0x68,0x78,0x2b,0x34,0xbc,0x15,0x1a,0xde,0x0a,0x0d,0x6f,0xe5,
|
||||
0x10,0xc0,0xff,0x01,0x48,0xf9,0x62,0xf7
|
||||
};
|
||||
|
||||
const unsigned int font_proggyClean_compressed_size=5936;
|
||||
|
|
|
|||
11300
src/gui/font_ptMono.cpp
11300
src/gui/font_ptMono.cpp
File diff suppressed because it is too large
Load diff
233419
src/gui/font_unifont.cpp
233419
src/gui/font_unifont.cpp
File diff suppressed because it is too large
Load diff
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "fonts.h"
|
||||
|
||||
const unsigned int* builtinFont[]={
|
||||
const unsigned char* builtinFont[]={
|
||||
font_plexSans_compressed_data,
|
||||
font_liberationSans_compressed_data,
|
||||
font_exo_compressed_data,
|
||||
|
|
@ -38,7 +38,7 @@ const unsigned int builtinFontLen[]={
|
|||
font_unifont_compressed_size
|
||||
};
|
||||
|
||||
const unsigned int* builtinFontM[]={
|
||||
const unsigned char* builtinFontM[]={
|
||||
font_plexMono_compressed_data,
|
||||
font_mononoki_compressed_data,
|
||||
font_ptMono_compressed_data,
|
||||
|
|
|
|||
|
|
@ -23,33 +23,37 @@
|
|||
#ifndef _FONTS_H
|
||||
#define _FONTS_H
|
||||
extern const unsigned int font_exo_compressed_size;
|
||||
extern const unsigned int font_exo_compressed_data[];
|
||||
extern const unsigned char font_exo_compressed_data[];
|
||||
extern const unsigned int font_liberationSans_compressed_size;
|
||||
extern const unsigned int font_liberationSans_compressed_data[];
|
||||
extern const unsigned char font_liberationSans_compressed_data[];
|
||||
extern const unsigned int font_mononoki_compressed_size;
|
||||
extern const unsigned int font_mononoki_compressed_data[];
|
||||
extern const unsigned char font_mononoki_compressed_data[];
|
||||
extern const unsigned int font_plexSans_compressed_size;
|
||||
extern const unsigned int font_plexSans_compressed_data[];
|
||||
extern const unsigned char font_plexSans_compressed_data[];
|
||||
extern const unsigned int font_plexSansJP_compressed_size;
|
||||
extern const unsigned char font_plexSansJP_compressed_data[];
|
||||
extern const unsigned int font_plexSansKR_compressed_size;
|
||||
extern const unsigned char font_plexSansKR_compressed_data[];
|
||||
extern const unsigned int font_plexMono_compressed_size;
|
||||
extern const unsigned int font_plexMono_compressed_data[];
|
||||
extern const unsigned char font_plexMono_compressed_data[];
|
||||
extern const unsigned int font_proggyClean_compressed_size;
|
||||
extern const unsigned int font_proggyClean_compressed_data[];
|
||||
extern const unsigned char font_proggyClean_compressed_data[];
|
||||
extern const unsigned int font_ptMono_compressed_size;
|
||||
extern const unsigned int font_ptMono_compressed_data[];
|
||||
extern const unsigned char font_ptMono_compressed_data[];
|
||||
extern const unsigned int font_unifont_compressed_size;
|
||||
extern const unsigned int font_unifont_compressed_data[];
|
||||
extern const unsigned char font_unifont_compressed_data[];
|
||||
extern const unsigned int iconFont_compressed_size;
|
||||
extern const unsigned int iconFont_compressed_data[];
|
||||
extern const unsigned char iconFont_compressed_data[];
|
||||
extern const unsigned int furIcons_compressed_size;
|
||||
extern const unsigned int furIcons_compressed_data[];
|
||||
extern const unsigned char furIcons_compressed_data[];
|
||||
|
||||
extern const unsigned int* builtinFont[];
|
||||
extern const unsigned char* builtinFont[];
|
||||
extern const unsigned int builtinFontLen[];
|
||||
extern const unsigned int* builtinFontM[];
|
||||
extern const unsigned char* builtinFontM[];
|
||||
extern const unsigned int builtinFontMLen[];
|
||||
#endif
|
||||
|
||||
// "(Glimmer of hope: the atlas system will be rewritten in the future to make scaling more flexible.)""
|
||||
// not just that. somebody rewrite it already so I can load these glyphs at run-time and support
|
||||
// all languages at once, instead of having to load Unifont's 65k+ characters and blow the GPU up in the
|
||||
// process!
|
||||
// process!
|
||||
|
|
|
|||
125
src/gui/fontzlib.cpp
Normal file
125
src/gui/fontzlib.cpp
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2024 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 <zlib.h>
|
||||
|
||||
#define FONT_READ_SIZE 262144
|
||||
|
||||
struct InflateBlock {
|
||||
unsigned char* buf;
|
||||
size_t len;
|
||||
size_t blockSize;
|
||||
InflateBlock(size_t s) {
|
||||
buf=new unsigned char[s];
|
||||
len=s;
|
||||
blockSize=0;
|
||||
}
|
||||
~InflateBlock() {
|
||||
delete[] buf;
|
||||
len=0;
|
||||
}
|
||||
};
|
||||
|
||||
ImFont* FurnaceGUI::addFontZlib(const void* data, size_t len, float size_pixels, const ImFontConfig* font_cfg, const ImWchar* glyph_ranges) {
|
||||
z_stream zl;
|
||||
memset(&zl,0,sizeof(z_stream));
|
||||
logV("addFontZlib...");
|
||||
|
||||
zl.avail_in=len;
|
||||
zl.next_in=(Bytef*)data;
|
||||
zl.zalloc=NULL;
|
||||
zl.zfree=NULL;
|
||||
zl.opaque=NULL;
|
||||
|
||||
int nextErr;
|
||||
nextErr=inflateInit(&zl);
|
||||
if (nextErr!=Z_OK) {
|
||||
if (zl.msg==NULL) {
|
||||
logD("zlib error: unknown! %d",nextErr);
|
||||
} else {
|
||||
logD("zlib error: %s",zl.msg);
|
||||
}
|
||||
inflateEnd(&zl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::vector<InflateBlock*> blocks;
|
||||
while (true) {
|
||||
InflateBlock* ib=new InflateBlock(FONT_READ_SIZE);
|
||||
zl.next_out=ib->buf;
|
||||
zl.avail_out=ib->len;
|
||||
|
||||
nextErr=inflate(&zl,Z_SYNC_FLUSH);
|
||||
if (nextErr!=Z_OK && nextErr!=Z_STREAM_END) {
|
||||
if (zl.msg==NULL) {
|
||||
logD("zlib error: unknown error! %d",nextErr);
|
||||
} else {
|
||||
logD("zlib inflate: %s",zl.msg);
|
||||
}
|
||||
for (InflateBlock* i: blocks) delete i;
|
||||
blocks.clear();
|
||||
delete ib;
|
||||
inflateEnd(&zl);
|
||||
return NULL;
|
||||
}
|
||||
ib->blockSize=ib->len-zl.avail_out;
|
||||
blocks.push_back(ib);
|
||||
if (nextErr==Z_STREAM_END) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
nextErr=inflateEnd(&zl);
|
||||
if (nextErr!=Z_OK) {
|
||||
if (zl.msg==NULL) {
|
||||
logD("zlib end error: unknown error! %d",nextErr);
|
||||
} else {
|
||||
logD("zlib end: %s",zl.msg);
|
||||
}
|
||||
for (InflateBlock* i: blocks) delete i;
|
||||
blocks.clear();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t finalSize=0;
|
||||
size_t curSeek=0;
|
||||
for (InflateBlock* i: blocks) {
|
||||
finalSize+=i->blockSize;
|
||||
}
|
||||
if (finalSize<1) {
|
||||
logD("compressed too small!");
|
||||
lastError="file too small";
|
||||
for (InflateBlock* i: blocks) delete i;
|
||||
blocks.clear();
|
||||
return NULL;
|
||||
}
|
||||
unsigned char* finalData=new unsigned char[finalSize];
|
||||
for (InflateBlock* i: blocks) {
|
||||
memcpy(&finalData[curSeek],i->buf,i->blockSize);
|
||||
curSeek+=i->blockSize;
|
||||
delete i;
|
||||
}
|
||||
blocks.clear();
|
||||
len=finalSize;
|
||||
|
||||
ImFontConfig fontConfig=(font_cfg==NULL)?ImFontConfig():(*font_cfg);
|
||||
fontConfig.FontDataOwnedByAtlas=true;
|
||||
|
||||
return ImGui::GetIO().Fonts->AddFontFromMemoryTTF(finalData,finalSize,size_pixels,&fontConfig,glyph_ranges);
|
||||
}
|
||||
302
src/gui/gif_load.h
Normal file
302
src/gui/gif_load.h
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
#ifndef GIF_LOAD_H
|
||||
#define GIF_LOAD_H
|
||||
|
||||
/** gif_load: A slim, fast and header-only GIF loader written in C.
|
||||
Original author: hidefromkgb (hidefromkgb@gmail.com)
|
||||
_________________________________________________________________________
|
||||
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
_________________________________________________________________________
|
||||
**/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdint.h> /** imports uint8_t, uint16_t and uint32_t **/
|
||||
#ifndef GIF_MGET
|
||||
#include <stdlib.h>
|
||||
#define GIF_MGET(m,s,a,c) m = (uint8_t*)realloc((c)? 0 : m, (c)? s : 1UL);
|
||||
#endif
|
||||
#ifndef GIF_BIGE
|
||||
#define GIF_BIGE 0
|
||||
#endif
|
||||
#ifndef GIF_EXTR
|
||||
#define GIF_EXTR static
|
||||
#endif
|
||||
#define _GIF_SWAP(h) ((GIF_BIGE)? ((uint16_t)(h << 8) | (h >> 8)) : h)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct GIF_WHDR { /** ======== frame writer info: ======== **/
|
||||
long xdim, ydim, clrs, /** global dimensions, palette size **/
|
||||
bkgd, tran, /** background index, transparent index **/
|
||||
intr, mode, /** interlace flag, frame blending mode **/
|
||||
frxd, fryd, frxo, fryo, /** current frame dimensions and offset **/
|
||||
time, ifrm, nfrm; /** delay, frame number, frame count **/
|
||||
uint8_t *bptr; /** frame pixel indices or metadata **/
|
||||
struct { /** [==== GIF RGB palette element: ====] **/
|
||||
uint8_t R, G, B; /** [color values - red, green, blue ] **/
|
||||
} *cpal; /** current palette **/
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
enum {GIF_NONE = 0, GIF_CURR = 1, GIF_BKGD = 2, GIF_PREV = 3};
|
||||
|
||||
/** [ internal function, do not use ] **/
|
||||
static long _GIF_SkipChunk(uint8_t **buff, long size) {
|
||||
long skip;
|
||||
|
||||
for (skip = 2, ++size, ++(*buff); ((size -= skip) > 0) && (skip > 1);
|
||||
*buff += (skip = 1 + **buff));
|
||||
return size;
|
||||
}
|
||||
|
||||
/** [ internal function, do not use ] **/
|
||||
static long _GIF_LoadHeader(unsigned gflg, uint8_t **buff, void **rpal,
|
||||
unsigned fflg, long *size, long flen) {
|
||||
if (flen && (!(*buff += flen) || ((*size -= flen) <= 0)))
|
||||
return -2; /** v--[ 0x80: "palette is present" flag ]--, **/
|
||||
if (flen && (fflg & 0x80)) { /** local palette has priority | **/
|
||||
*rpal = *buff; /** [ 3L: 3 uint8_t color channels ]--, | **/
|
||||
*buff += (flen = 2 << (fflg & 7)) * 3L; /** <--| | **/
|
||||
return ((*size -= flen * 3L) > 0)? flen : -1; /** <--' | **/
|
||||
} /** no local palette found, checking for the global one | **/
|
||||
return (gflg & 0x80)? (2 << (gflg & 7)) : 0; /** <-----' **/
|
||||
}
|
||||
|
||||
/** [ internal function, do not use ] **/
|
||||
static long _GIF_LoadFrame(uint8_t **buff, long *size,
|
||||
uint8_t *bptr, uint8_t *blen) {
|
||||
typedef uint16_t GIF_H;
|
||||
const long GIF_HLEN = sizeof(GIF_H), /** to rid the scope of sizeof **/
|
||||
GIF_CLEN = 1 << 12; /** code table length: 4096 items **/
|
||||
GIF_H accu, mask; /** bit accumulator / bit mask **/
|
||||
long ctbl, iter, /** last code table index / index string iterator **/
|
||||
prev, curr, /** codes from the stream: previous / current **/
|
||||
ctsz, ccsz, /** code table bit sizes: min LZW / current **/
|
||||
bseq, bszc; /** counters: block sequence / bit size **/
|
||||
uint32_t *code = (uint32_t*)bptr - GIF_CLEN; /** code table pointer **/
|
||||
|
||||
/** preparing initial values **/
|
||||
if ((--(*size) <= GIF_HLEN) || !*++(*buff))
|
||||
return -4; /** unexpected end of the stream: insufficient size **/
|
||||
mask = (GIF_H)((1 << (ccsz = (ctsz = *(*buff - 1)) + 1)) - 1);
|
||||
if ((ctsz < 2) || (ctsz > 8))
|
||||
return -3; /** min LZW size is out of its nominal [2; 8] bounds **/
|
||||
if ((ctbl = (1L << ctsz)) != (mask & _GIF_SWAP(*(GIF_H*)(*buff + 1))))
|
||||
return -2; /** initial code is not equal to min LZW size **/
|
||||
for (curr = ++ctbl; curr; code[--curr] = 0); /** actual color codes **/
|
||||
|
||||
/** getting codes from stream (--size makes up for end-of-stream mark) **/
|
||||
for (--(*size), bszc = -ccsz, prev = curr = 0;
|
||||
((*size -= (bseq = *(*buff)++) + 1) >= 0) && bseq; *buff += bseq)
|
||||
for (; bseq > 0; bseq -= GIF_HLEN, *buff += GIF_HLEN)
|
||||
for (accu = (GIF_H)(_GIF_SWAP(*(GIF_H*)*buff)
|
||||
& ((bseq < GIF_HLEN)? ((1U << (8 * bseq)) - 1U) : ~0U)),
|
||||
curr |= accu << (ccsz + bszc), accu = (GIF_H)(accu >> -bszc),
|
||||
bszc += 8 * ((bseq < GIF_HLEN)? bseq : GIF_HLEN);
|
||||
bszc >= 0; bszc -= ccsz, prev = curr, curr = accu,
|
||||
accu = (GIF_H)(accu >> ccsz))
|
||||
if (((curr &= mask) & ~1L) == (1L << ctsz)) {
|
||||
if (~(ctbl = curr + 1) & 1) /** end-of-data code (ED). **/
|
||||
/** -1: no end-of-stream mark after ED; 1: decoded **/
|
||||
return (*((*buff += bseq + 1) - 1))? -1 : 1;
|
||||
mask = (GIF_H)((1 << (ccsz = ctsz + 1)) - 1);
|
||||
} /** ^- table drop code (TD). TD = 1 << ctsz, ED = TD + 1 **/
|
||||
else { /** single-pixel (SP) or multi-pixel (MP) code. **/
|
||||
if (ctbl < GIF_CLEN) { /** is the code table full? **/
|
||||
if ((ctbl == mask) && (ctbl < GIF_CLEN - 1)) {
|
||||
mask = (GIF_H)(mask + mask + 1);
|
||||
ccsz++; /** yes; extending **/
|
||||
} /** prev = TD? => curr < ctbl = prev **/
|
||||
code[ctbl] = (uint32_t)prev + (code[prev] & 0xFFF000);
|
||||
} /** appending SP / MP decoded pixels to the frame **/
|
||||
prev = (long)code[iter = (ctbl > curr)? curr : prev];
|
||||
if ((bptr += (prev = (prev >> 12) & 0xFFF)) > blen)
|
||||
continue; /** skipping pixels above frame capacity **/
|
||||
for (prev++; (iter &= 0xFFF) >> ctsz;
|
||||
*bptr-- = (uint8_t)((iter = (long)code[iter]) >> 24));
|
||||
(bptr += prev)[-prev] = (uint8_t)iter;
|
||||
if (ctbl < GIF_CLEN) { /** appending the code table **/
|
||||
if (ctbl == curr)
|
||||
*bptr++ = (uint8_t)iter;
|
||||
else if (ctbl < curr)
|
||||
return -5; /** wrong code in the stream **/
|
||||
code[ctbl++] += ((uint32_t)iter << 24) + 0x1000;
|
||||
}
|
||||
} /** 0: no ED before end-of-stream mark; -4: see above **/
|
||||
return (++(*size) >= 0)? 0 : -4; /** ^- N.B.: 0 error is recoverable **/
|
||||
}
|
||||
|
||||
/** _________________________________________________________________________
|
||||
The main loading function. Returns the total number of frames if the data
|
||||
includes proper GIF ending, and otherwise it returns the number of frames
|
||||
loaded per current call, multiplied by -1. So, the data may be incomplete
|
||||
and in this case the function can be called again when more data arrives,
|
||||
just remember to keep SKIP up to date.
|
||||
_________________________________________________________________________
|
||||
DATA: raw data chunk, may be partial
|
||||
SIZE: size of the data chunk that`s currently present
|
||||
GWFR: frame writer function, MANDATORY
|
||||
EAMF: metadata reader function, set to 0 if not needed
|
||||
ANIM: implementation-specific data (e.g. a structure or a pointer to it)
|
||||
SKIP: number of frames to skip before resuming
|
||||
**/
|
||||
GIF_EXTR long GIF_Load(void *data, long size,
|
||||
void (*gwfr)(void*, struct GIF_WHDR*),
|
||||
void (*eamf)(void*, struct GIF_WHDR*),
|
||||
void *anim, long skip) {
|
||||
const long GIF_BLEN = (1 << 12) * sizeof(uint32_t);
|
||||
const uint8_t GIF_EHDM = 0x21, /** extension header mark **/
|
||||
GIF_FHDM = 0x2C, /** frame header mark **/
|
||||
GIF_EOFM = 0x3B, /** end-of-file mark **/
|
||||
GIF_EGCM = 0xF9, /** extension: graphics control mark **/
|
||||
GIF_EAMM = 0xFF; /** extension: app metadata mark **/
|
||||
#pragma pack(push, 1)
|
||||
struct GIF_GHDR { /** ========== GLOBAL GIF HEADER: ========== **/
|
||||
uint8_t head[6]; /** 'GIF87a' / 'GIF89a' header signature **/
|
||||
uint16_t xdim, ydim; /** total image width, total image height **/
|
||||
uint8_t flgs; /** FLAGS:
|
||||
GlobalPlt bit 7 1: global palette exists
|
||||
0: local in each frame
|
||||
ClrRes bit 6-4 bits/channel = ClrRes+1
|
||||
[reserved] bit 3 0
|
||||
PixelBits bit 2-0 |Plt| = 2 * 2^PixelBits
|
||||
**/
|
||||
uint8_t bkgd, aspr; /** background color index, aspect ratio **/
|
||||
} *ghdr = (struct GIF_GHDR*)data;
|
||||
struct GIF_FHDR { /** ======= GIF FRAME MASTER HEADER: ======= **/
|
||||
uint16_t frxo, fryo; /** offset of this frame in a "full" image **/
|
||||
uint16_t frxd, fryd; /** frame width, frame height **/
|
||||
uint8_t flgs; /** FLAGS:
|
||||
LocalPlt bit 7 1: local palette exists
|
||||
0: global is used
|
||||
Interlaced bit 6 1: interlaced frame
|
||||
0: non-interlaced frame
|
||||
Sorted bit 5 usually 0
|
||||
[reserved] bit 4-3 [undefined]
|
||||
PixelBits bit 2-0 |Plt| = 2 * 2^PixelBits
|
||||
**/
|
||||
} *fhdr;
|
||||
struct GIF_EGCH { /** ==== [EXT] GRAPHICS CONTROL HEADER: ==== **/
|
||||
uint8_t flgs; /** FLAGS:
|
||||
[reserved] bit 7-5 [undefined]
|
||||
BlendMode bit 4-2 000: not set; static GIF
|
||||
001: leave result as is
|
||||
010: restore background
|
||||
011: restore previous
|
||||
1--: [undefined]
|
||||
UserInput bit 1 1: show frame till input
|
||||
0: default; ~99% of GIFs
|
||||
TransColor bit 0 1: got transparent color
|
||||
0: frame is fully opaque
|
||||
**/
|
||||
uint16_t time; /** delay in GIF time units; 1 unit = 10 ms **/
|
||||
uint8_t tran; /** transparent color index **/
|
||||
} *egch = 0;
|
||||
#pragma pack(pop)
|
||||
struct GIF_WHDR wtmp, whdr;
|
||||
long desc, blen;
|
||||
uint8_t *buff;
|
||||
|
||||
memset(&wtmp,0,sizeof(struct GIF_WHDR));
|
||||
memset(&whdr,0,sizeof(struct GIF_WHDR));
|
||||
|
||||
/** checking if the stream is not empty and has a 'GIF8[79]a' signature,
|
||||
the data has sufficient size and frameskip value is non-negative **/
|
||||
if (!ghdr || (size <= (long)sizeof(*ghdr)) || (*(buff = ghdr->head) != 71)
|
||||
|| (buff[1] != 73) || (buff[2] != 70) || (buff[3] != 56) || (skip < 0)
|
||||
|| ((buff[4] != 55) && (buff[4] != 57)) || (buff[5] != 97) || !gwfr)
|
||||
return 0;
|
||||
|
||||
buff = (uint8_t*)(ghdr + 1) /** skipping the global header and palette **/
|
||||
+ _GIF_LoadHeader(ghdr->flgs, 0, 0, 0, 0, 0L) * 3L;
|
||||
if ((size -= buff - (uint8_t*)ghdr) <= 0)
|
||||
return 0;
|
||||
|
||||
whdr.xdim = _GIF_SWAP(ghdr->xdim);
|
||||
whdr.ydim = _GIF_SWAP(ghdr->ydim);
|
||||
for (whdr.bptr = buff, whdr.bkgd = ghdr->bkgd, blen = --size;
|
||||
(blen >= 0) && ((desc = *whdr.bptr++) != GIF_EOFM); /** sic: '>= 0' **/
|
||||
blen = _GIF_SkipChunk(&whdr.bptr, blen) - 1) /** count all frames **/
|
||||
if (desc == GIF_FHDM) {
|
||||
fhdr = (struct GIF_FHDR*)whdr.bptr;
|
||||
if (_GIF_LoadHeader(ghdr->flgs, &whdr.bptr, (void**)&whdr.cpal,
|
||||
fhdr->flgs, &blen, sizeof(*fhdr)) <= 0)
|
||||
break;
|
||||
whdr.frxd = _GIF_SWAP(fhdr->frxd);
|
||||
whdr.fryd = _GIF_SWAP(fhdr->fryd);
|
||||
whdr.frxo = (whdr.frxd > whdr.frxo)? whdr.frxd : whdr.frxo;
|
||||
whdr.fryo = (whdr.fryd > whdr.fryo)? whdr.fryd : whdr.fryo;
|
||||
whdr.ifrm++;
|
||||
}
|
||||
blen = whdr.frxo * whdr.fryo * (long)sizeof(*whdr.bptr);
|
||||
GIF_MGET(whdr.bptr, (unsigned long)(blen + GIF_BLEN + 2), anim, 1)
|
||||
whdr.nfrm = (desc != GIF_EOFM)? -whdr.ifrm : whdr.ifrm;
|
||||
for (whdr.bptr += GIF_BLEN, whdr.ifrm = -1; blen /** load all frames **/
|
||||
&& (skip < ((whdr.nfrm < 0)? -whdr.nfrm : whdr.nfrm)) && (size >= 0);
|
||||
size = (desc != GIF_EOFM)? ((desc != GIF_FHDM) || (skip > whdr.ifrm))?
|
||||
_GIF_SkipChunk(&buff, size) - 1 : size - 1 : -1)
|
||||
if ((desc = *buff++) == GIF_FHDM) { /** found a frame **/
|
||||
whdr.intr = !!((fhdr = (struct GIF_FHDR*)buff)->flgs & 0x40);
|
||||
*(void**)&whdr.cpal = (void*)(ghdr + 1); /** interlaced? -^ **/
|
||||
whdr.clrs = _GIF_LoadHeader(ghdr->flgs, &buff, (void**)&whdr.cpal,
|
||||
fhdr->flgs, &size, sizeof(*fhdr));
|
||||
if ((skip <= ++whdr.ifrm) && ((whdr.clrs <= 0)
|
||||
|| (_GIF_LoadFrame(&buff, &size,
|
||||
whdr.bptr, whdr.bptr + blen) < 0)))
|
||||
size = -(whdr.ifrm--) - 1; /** failed to load the frame **/
|
||||
else if (skip <= whdr.ifrm) {
|
||||
whdr.frxd = _GIF_SWAP(fhdr->frxd);
|
||||
whdr.fryd = _GIF_SWAP(fhdr->fryd);
|
||||
whdr.frxo = _GIF_SWAP(fhdr->frxo);
|
||||
whdr.fryo = _GIF_SWAP(fhdr->fryo);
|
||||
whdr.time = (egch)? _GIF_SWAP(egch->time) : 0;
|
||||
whdr.tran = (egch && (egch->flgs & 0x01))? egch->tran : -1;
|
||||
whdr.time = (egch && (egch->flgs & 0x02))? -whdr.time - 1
|
||||
: whdr.time;
|
||||
whdr.mode = (egch && !(egch->flgs & 0x10))?
|
||||
(egch->flgs & 0x0C) >> 2 : GIF_NONE;
|
||||
egch = 0;
|
||||
wtmp = whdr;
|
||||
gwfr(anim, &wtmp); /** passing the frame to the caller **/
|
||||
}
|
||||
}
|
||||
else if (desc == GIF_EHDM) { /** found an extension **/
|
||||
if (*buff == GIF_EGCM) /** graphics control ext. **/
|
||||
egch = (struct GIF_EGCH*)(buff + 1 + 1);
|
||||
else if ((*buff == GIF_EAMM) && eamf) { /** app metadata ext. **/
|
||||
wtmp = whdr;
|
||||
wtmp.bptr = buff + 1 + 1; /** just passing the raw chunk **/
|
||||
eamf(anim, &wtmp);
|
||||
}
|
||||
}
|
||||
whdr.bptr -= GIF_BLEN; /** for excess pixel codes ----v (here & above) **/
|
||||
GIF_MGET(whdr.bptr, (unsigned long)(blen + GIF_BLEN + 2), anim, 0)
|
||||
return (whdr.nfrm < 0)? (skip - whdr.ifrm - 1) : (whdr.ifrm + 1);
|
||||
}
|
||||
|
||||
#undef _GIF_SWAP
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /** GIF_LOAD_H **/
|
||||
|
|
@ -32,10 +32,10 @@ void FurnaceGUI::drawGrooves() {
|
|||
}
|
||||
if (!groovesOpen) return;
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(64.0f*dpiScale,32.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||
if (ImGui::Begin("Grooves",&groovesOpen,globalWinFlags)) {
|
||||
if (ImGui::Begin("Grooves",&groovesOpen,globalWinFlags,_("Grooves"))) {
|
||||
int delGroove=-1;
|
||||
|
||||
ImGui::Text("use effect 09xx to select a groove pattern.");
|
||||
ImGui::Text(_("use effect 09xx to select a groove pattern."));
|
||||
if (!e->song.grooves.empty()) if (ImGui::BeginTable("GrooveList",3,ImGuiTableFlags_Borders)) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch);
|
||||
|
|
@ -45,7 +45,7 @@ void FurnaceGUI::drawGrooves() {
|
|||
ImGui::TableNextColumn();
|
||||
ImGui::Text("#");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("pattern");
|
||||
ImGui::Text(_("pattern"));
|
||||
ImGui::TableNextColumn();
|
||||
// ImGui::Text("remove"); removed because the text clips from the fixed width
|
||||
|
||||
|
|
@ -129,7 +129,7 @@ void FurnaceGUI::drawGrooves() {
|
|||
}
|
||||
popDestColor();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("remove");
|
||||
ImGui::SetTooltip(_("remove"));
|
||||
}
|
||||
|
||||
index++;
|
||||
|
|
|
|||
2782
src/gui/gui.cpp
2782
src/gui/gui.cpp
File diff suppressed because it is too large
Load diff
428
src/gui/gui.h
428
src/gui/gui.h
|
|
@ -36,6 +36,8 @@
|
|||
|
||||
#include "fileDialog.h"
|
||||
|
||||
#define FURNACE_APP_ID "org.tildearrow.furnace"
|
||||
|
||||
#define rightClickable if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) ImGui::SetKeyboardFocusHere(-1);
|
||||
#define ctrlWheeling ((ImGui::IsKeyDown(ImGuiKey_LeftCtrl) || ImGui::IsKeyDown(ImGuiKey_RightCtrl)) && wheelY!=0)
|
||||
|
||||
|
|
@ -43,7 +45,7 @@
|
|||
#define unimportant(x) if (x) {handleUnimportant}
|
||||
|
||||
#define MARK_MODIFIED modified=true;
|
||||
#define WAKE_UP drawHalt=16;
|
||||
#define WAKE_UP drawHalt=5;
|
||||
|
||||
#define RESET_WAVE_MACRO_ZOOM \
|
||||
for (DivInstrument* _wi: e->song.ins) { \
|
||||
|
|
@ -56,7 +58,7 @@
|
|||
// for now
|
||||
#define NOTIFY_LONG_HOLD \
|
||||
if (vibrator && vibratorAvailable) { \
|
||||
if (SDL_HapticRumblePlay(vibrator,0.5f,20)!=0) { \
|
||||
if (SDL_HapticRumblePlay(vibrator,settings.vibrationStrength,settings.vibrationLength)!=0) { \
|
||||
logV("could not vibrate: %s!",SDL_GetError()); \
|
||||
} \
|
||||
} else { \
|
||||
|
|
@ -70,25 +72,69 @@
|
|||
|
||||
enum FurnaceGUIRenderBackend {
|
||||
GUI_BACKEND_SDL=0,
|
||||
GUI_BACKEND_GL,
|
||||
GUI_BACKEND_DX11
|
||||
GUI_BACKEND_GL3,
|
||||
GUI_BACKEND_GL2,
|
||||
GUI_BACKEND_GL1,
|
||||
GUI_BACKEND_DX11,
|
||||
GUI_BACKEND_DX9,
|
||||
GUI_BACKEND_METAL,
|
||||
GUI_BACKEND_SOFTWARE
|
||||
};
|
||||
|
||||
#ifdef HAVE_RENDER_DX11
|
||||
#define GUI_BACKEND_DEFAULT GUI_BACKEND_DX11
|
||||
#define GUI_BACKEND_DEFAULT_NAME "DirectX 11"
|
||||
#define GUI_BACKEND_DEFAULT GUI_BACKEND_DX11
|
||||
#define GUI_BACKEND_DEFAULT_NAME "DirectX 11"
|
||||
#else
|
||||
#ifdef HAVE_RENDER_GL
|
||||
#define GUI_BACKEND_DEFAULT GUI_BACKEND_GL
|
||||
#define GUI_BACKEND_DEFAULT_NAME "OpenGL"
|
||||
#else
|
||||
#ifdef HAVE_RENDER_SDL
|
||||
#define GUI_BACKEND_DEFAULT GUI_BACKEND_SDL
|
||||
#define GUI_BACKEND_DEFAULT_NAME "SDL"
|
||||
#else
|
||||
#error how did you manage to do that?
|
||||
#ifdef HAVE_RENDER_GL
|
||||
#ifdef SUPPORT_XP
|
||||
#define GUI_BACKEND_DEFAULT GUI_BACKEND_GL1
|
||||
#define GUI_BACKEND_DEFAULT_NAME "OpenGL 1.1"
|
||||
#else
|
||||
#ifdef USE_GLES
|
||||
#define GUI_BACKEND_DEFAULT GUI_BACKEND_GL3
|
||||
#define GUI_BACKEND_DEFAULT_NAME "OpenGL ES 2.0"
|
||||
#else
|
||||
#define GUI_BACKEND_DEFAULT GUI_BACKEND_GL3
|
||||
#define GUI_BACKEND_DEFAULT_NAME "OpenGL 3.0"
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#ifdef HAVE_RENDER_SDL
|
||||
#define GUI_BACKEND_DEFAULT GUI_BACKEND_SDL
|
||||
#define GUI_BACKEND_DEFAULT_NAME "SDL"
|
||||
#else
|
||||
#define GUI_BACKEND_DEFAULT GUI_BACKEND_SOFTWARE
|
||||
#define GUI_BACKEDN_DEFAULT_NAME "Software"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_XP
|
||||
#define GUI_WIDTH_DEFAULT 800
|
||||
#define GUI_HEIGHT_DEFAULT 600
|
||||
#define GUI_MAIN_FONT_DEFAULT 3
|
||||
#define GUI_PAT_FONT_DEFAULT 3
|
||||
#define GUI_FONT_SIZE_DEFAULT 13
|
||||
#define GUI_ICON_SIZE_DEFAULT 12
|
||||
#define GUI_OVERSAMPLE_DEFAULT 1
|
||||
#define GUI_FONT_ANTIALIAS_DEFAULT 0
|
||||
#define GUI_FONT_HINTING_DEFAULT 1
|
||||
#define GUI_DECORATIONS_DEFAULT 0
|
||||
#else
|
||||
#define GUI_WIDTH_DEFAULT 1280
|
||||
#define GUI_HEIGHT_DEFAULT 800
|
||||
#define GUI_MAIN_FONT_DEFAULT 0
|
||||
#define GUI_PAT_FONT_DEFAULT 0
|
||||
#define GUI_FONT_SIZE_DEFAULT 18
|
||||
#define GUI_ICON_SIZE_DEFAULT 16
|
||||
#define GUI_OVERSAMPLE_DEFAULT 2
|
||||
#define GUI_FONT_ANTIALIAS_DEFAULT 1
|
||||
#define GUI_FONT_HINTING_DEFAULT 0
|
||||
#define GUI_DECORATIONS_DEFAULT 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MOMO
|
||||
#define ngettext momo_ngettext
|
||||
#endif
|
||||
|
||||
// TODO:
|
||||
|
|
@ -231,10 +277,15 @@ enum FurnaceGUIColors {
|
|||
GUI_COLOR_FM_SSG,
|
||||
GUI_COLOR_FM_WAVE,
|
||||
|
||||
GUI_COLOR_MACRO_HIGHLIGHT,
|
||||
GUI_COLOR_MACRO_VOLUME,
|
||||
GUI_COLOR_MACRO_PITCH,
|
||||
GUI_COLOR_MACRO_OTHER,
|
||||
GUI_COLOR_MACRO_WAVE,
|
||||
GUI_COLOR_MACRO_NOISE,
|
||||
GUI_COLOR_MACRO_FILTER,
|
||||
GUI_COLOR_MACRO_ENVELOPE,
|
||||
GUI_COLOR_MACRO_GLOBAL,
|
||||
|
||||
GUI_COLOR_INSTR_STD,
|
||||
GUI_COLOR_INSTR_FM,
|
||||
|
|
@ -298,6 +349,8 @@ enum FurnaceGUIColors {
|
|||
GUI_COLOR_INSTR_NDS,
|
||||
GUI_COLOR_INSTR_GBA_DMA,
|
||||
GUI_COLOR_INSTR_GBA_MINMOD,
|
||||
GUI_COLOR_INSTR_BIFURCATOR,
|
||||
GUI_COLOR_INSTR_SID2,
|
||||
GUI_COLOR_INSTR_UNKNOWN,
|
||||
|
||||
GUI_COLOR_CHANNEL_BG,
|
||||
|
|
@ -485,6 +538,7 @@ enum FurnaceGUIWindows {
|
|||
GUI_WINDOW_INTRO_MON,
|
||||
GUI_WINDOW_MEMORY,
|
||||
GUI_WINDOW_CS_PLAYER,
|
||||
GUI_WINDOW_USER_PRESETS,
|
||||
GUI_WINDOW_SPOILER
|
||||
};
|
||||
|
||||
|
|
@ -526,17 +580,20 @@ enum FurnaceGUIFileDialogs {
|
|||
GUI_FILE_INS_OPEN_REPLACE,
|
||||
GUI_FILE_INS_SAVE,
|
||||
GUI_FILE_INS_SAVE_DMP,
|
||||
GUI_FILE_INS_SAVE_ALL,
|
||||
GUI_FILE_WAVE_OPEN,
|
||||
GUI_FILE_WAVE_OPEN_REPLACE,
|
||||
GUI_FILE_WAVE_SAVE,
|
||||
GUI_FILE_WAVE_SAVE_DMW,
|
||||
GUI_FILE_WAVE_SAVE_RAW,
|
||||
GUI_FILE_WAVE_SAVE_ALL,
|
||||
GUI_FILE_SAMPLE_OPEN,
|
||||
GUI_FILE_SAMPLE_OPEN_RAW,
|
||||
GUI_FILE_SAMPLE_OPEN_REPLACE,
|
||||
GUI_FILE_SAMPLE_OPEN_REPLACE_RAW,
|
||||
GUI_FILE_SAMPLE_SAVE,
|
||||
GUI_FILE_SAMPLE_SAVE_RAW,
|
||||
GUI_FILE_SAMPLE_SAVE_ALL,
|
||||
GUI_FILE_EXPORT_AUDIO_ONE,
|
||||
GUI_FILE_EXPORT_AUDIO_PER_SYS,
|
||||
GUI_FILE_EXPORT_AUDIO_PER_CHANNEL,
|
||||
|
|
@ -551,9 +608,14 @@ enum FurnaceGUIFileDialogs {
|
|||
GUI_FILE_IMPORT_COLORS,
|
||||
GUI_FILE_IMPORT_KEYBINDS,
|
||||
GUI_FILE_IMPORT_LAYOUT,
|
||||
GUI_FILE_IMPORT_USER_PRESETS,
|
||||
GUI_FILE_IMPORT_USER_PRESETS_REPLACE,
|
||||
GUI_FILE_IMPORT_CONFIG,
|
||||
GUI_FILE_EXPORT_COLORS,
|
||||
GUI_FILE_EXPORT_KEYBINDS,
|
||||
GUI_FILE_EXPORT_LAYOUT,
|
||||
GUI_FILE_EXPORT_USER_PRESETS,
|
||||
GUI_FILE_EXPORT_CONFIG,
|
||||
GUI_FILE_YRW801_ROM_OPEN,
|
||||
GUI_FILE_TG100_ROM_OPEN,
|
||||
GUI_FILE_MU5_ROM_OPEN,
|
||||
|
|
@ -578,6 +640,8 @@ enum FurnaceGUIWarnings {
|
|||
GUI_WARN_SUBSONG_DEL,
|
||||
GUI_WARN_SYSTEM_DEL,
|
||||
GUI_WARN_CLEAR_HISTORY,
|
||||
GUI_WARN_CV,
|
||||
GUI_WARN_RESET_CONFIG,
|
||||
GUI_WARN_GENERIC
|
||||
};
|
||||
|
||||
|
|
@ -586,9 +650,9 @@ enum FurnaceGUIExportTypes {
|
|||
|
||||
GUI_EXPORT_AUDIO=0,
|
||||
GUI_EXPORT_VGM,
|
||||
GUI_EXPORT_ROM,
|
||||
GUI_EXPORT_ZSM,
|
||||
GUI_EXPORT_CMD_STREAM,
|
||||
GUI_EXPORT_AMIGA_VAL,
|
||||
GUI_EXPORT_TEXT,
|
||||
GUI_EXPORT_DMF
|
||||
};
|
||||
|
|
@ -677,6 +741,7 @@ enum FurnaceGUIActions {
|
|||
GUI_ACTION_WINDOW_XY_OSC,
|
||||
GUI_ACTION_WINDOW_MEMORY,
|
||||
GUI_ACTION_WINDOW_CS_PLAYER,
|
||||
GUI_ACTION_WINDOW_USER_PRESETS,
|
||||
|
||||
GUI_ACTION_COLLAPSE_WINDOW,
|
||||
GUI_ACTION_CLOSE_WINDOW,
|
||||
|
|
@ -723,6 +788,10 @@ enum FurnaceGUIActions {
|
|||
GUI_ACTION_PAT_SELECTION_END,
|
||||
GUI_ACTION_PAT_SELECTION_UP_COARSE,
|
||||
GUI_ACTION_PAT_SELECTION_DOWN_COARSE,
|
||||
GUI_ACTION_PAT_MOVE_UP,
|
||||
GUI_ACTION_PAT_MOVE_DOWN,
|
||||
GUI_ACTION_PAT_MOVE_LEFT_CHANNEL,
|
||||
GUI_ACTION_PAT_MOVE_RIGHT_CHANNEL,
|
||||
GUI_ACTION_PAT_DELETE,
|
||||
GUI_ACTION_PAT_PULL_DELETE,
|
||||
GUI_ACTION_PAT_INSERT,
|
||||
|
|
@ -747,6 +816,7 @@ enum FurnaceGUIActions {
|
|||
GUI_ACTION_PAT_LATCH,
|
||||
GUI_ACTION_PAT_SCROLL_MODE,
|
||||
GUI_ACTION_PAT_CLEAR_LATCH,
|
||||
GUI_ACTION_PAT_ABSORB_INSTRUMENT,
|
||||
GUI_ACTION_PAT_MAX,
|
||||
|
||||
GUI_ACTION_INS_LIST_MIN,
|
||||
|
|
@ -763,6 +833,7 @@ enum FurnaceGUIActions {
|
|||
GUI_ACTION_INS_LIST_UP,
|
||||
GUI_ACTION_INS_LIST_DOWN,
|
||||
GUI_ACTION_INS_LIST_DIR_VIEW,
|
||||
GUI_ACTION_INS_LIST_SAVE_ALL,
|
||||
GUI_ACTION_INS_LIST_MAX,
|
||||
|
||||
GUI_ACTION_WAVE_LIST_MIN,
|
||||
|
|
@ -780,6 +851,7 @@ enum FurnaceGUIActions {
|
|||
GUI_ACTION_WAVE_LIST_UP,
|
||||
GUI_ACTION_WAVE_LIST_DOWN,
|
||||
GUI_ACTION_WAVE_LIST_DIR_VIEW,
|
||||
GUI_ACTION_WAVE_LIST_SAVE_ALL,
|
||||
GUI_ACTION_WAVE_LIST_MAX,
|
||||
|
||||
GUI_ACTION_SAMPLE_LIST_MIN,
|
||||
|
|
@ -801,6 +873,7 @@ enum FurnaceGUIActions {
|
|||
GUI_ACTION_SAMPLE_LIST_STOP_PREVIEW,
|
||||
GUI_ACTION_SAMPLE_LIST_DIR_VIEW,
|
||||
GUI_ACTION_SAMPLE_LIST_MAKE_MAP,
|
||||
GUI_ACTION_SAMPLE_LIST_SAVE_ALL,
|
||||
GUI_ACTION_SAMPLE_LIST_MAX,
|
||||
|
||||
GUI_ACTION_SAMPLE_MIN,
|
||||
|
|
@ -887,12 +960,6 @@ enum FurnaceGUIChanOscRef {
|
|||
GUI_OSCREF_MAX
|
||||
};
|
||||
|
||||
enum FurnaceGUITutorials {
|
||||
GUI_TUTORIAL_OVERVIEW=0,
|
||||
|
||||
GUI_TUTORIAL_MAX
|
||||
};
|
||||
|
||||
enum PasteMode {
|
||||
GUI_PASTE_MODE_NORMAL=0,
|
||||
GUI_PASTE_MODE_MIX_FG,
|
||||
|
|
@ -1231,22 +1298,25 @@ struct Gradient2D {
|
|||
|
||||
struct FurnaceGUISysDefChip {
|
||||
DivSystem sys;
|
||||
float vol, pan;
|
||||
const char* flags;
|
||||
FurnaceGUISysDefChip(DivSystem s, float v, float p, const char* f):
|
||||
float vol, pan, panFR;
|
||||
String flags;
|
||||
FurnaceGUISysDefChip(DivSystem s, float v, float p, const char* f, float pf=0.0):
|
||||
sys(s),
|
||||
vol(v),
|
||||
pan(p),
|
||||
panFR(pf),
|
||||
flags(f) {}
|
||||
};
|
||||
|
||||
struct FurnaceGUISysDef {
|
||||
const char* name;
|
||||
const char* extra;
|
||||
String name;
|
||||
String extra;
|
||||
String definition;
|
||||
std::vector<FurnaceGUISysDefChip> orig;
|
||||
std::vector<FurnaceGUISysDef> subDefs;
|
||||
void bake();
|
||||
FurnaceGUISysDef(const char* n, std::initializer_list<FurnaceGUISysDefChip> def, const char* e=NULL);
|
||||
FurnaceGUISysDef(const char* n, const char* def, DivEngine* e);
|
||||
};
|
||||
|
||||
struct FurnaceGUISysCategory {
|
||||
|
|
@ -1261,31 +1331,6 @@ struct FurnaceGUISysCategory {
|
|||
description(NULL) {}
|
||||
};
|
||||
|
||||
typedef std::function<void()> TutorialFunc;
|
||||
|
||||
struct FurnaceGUITutorialStep {
|
||||
const char* text;
|
||||
int waitForTrigger;
|
||||
TutorialFunc run;
|
||||
TutorialFunc runBefore;
|
||||
TutorialFunc runAfter;
|
||||
|
||||
FurnaceGUITutorialStep(const char* t, int trigger=-1, TutorialFunc activeFunc=NULL, TutorialFunc beginFunc=NULL, TutorialFunc endFunc=NULL):
|
||||
text(t),
|
||||
waitForTrigger(trigger),
|
||||
run(activeFunc),
|
||||
runBefore(beginFunc),
|
||||
runAfter(endFunc) {}
|
||||
};
|
||||
|
||||
struct FurnaceGUITutorialDef {
|
||||
const char* name;
|
||||
std::vector<FurnaceGUITutorialStep> steps;
|
||||
FurnaceGUITutorialDef():
|
||||
name("Help!") {}
|
||||
FurnaceGUITutorialDef(const char* n, std::initializer_list<FurnaceGUITutorialStep> step);
|
||||
};
|
||||
|
||||
struct FurnaceGUIMacroDesc {
|
||||
DivInstrumentMacro* macro;
|
||||
int min, max;
|
||||
|
|
@ -1412,6 +1457,14 @@ struct FurnaceGUIWaveSizeEntry {
|
|||
sys(NULL) {}
|
||||
};
|
||||
|
||||
enum FurnaceGUITextureFormat: unsigned int {
|
||||
GUI_TEXFORMAT_UNKNOWN=0,
|
||||
GUI_TEXFORMAT_ABGR32=1,
|
||||
GUI_TEXFORMAT_ARGB32=2,
|
||||
GUI_TEXFORMAT_BGRA32=4,
|
||||
GUI_TEXFORMAT_RGBA32=8,
|
||||
};
|
||||
|
||||
class FurnaceGUITexture {
|
||||
};
|
||||
|
||||
|
|
@ -1439,6 +1492,16 @@ struct FurnaceGUIPerfMetric {
|
|||
elapsed(0) {}
|
||||
};
|
||||
|
||||
struct FurnaceGUIBackupEntry {
|
||||
String name;
|
||||
uint64_t size;
|
||||
struct tm lastEntryTime;
|
||||
FurnaceGUIBackupEntry():
|
||||
size(0) {
|
||||
memset(&lastEntryTime,0,sizeof(struct tm));
|
||||
}
|
||||
};
|
||||
|
||||
enum FurnaceGUIBlendMode {
|
||||
GUI_BLEND_MODE_NONE=0,
|
||||
GUI_BLEND_MODE_BLEND,
|
||||
|
|
@ -1449,16 +1512,21 @@ enum FurnaceGUIBlendMode {
|
|||
class FurnaceGUIRender {
|
||||
public:
|
||||
virtual ImTextureID getTextureID(FurnaceGUITexture* which);
|
||||
virtual float getTextureU(FurnaceGUITexture* which);
|
||||
virtual float getTextureV(FurnaceGUITexture* which);
|
||||
virtual FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which);
|
||||
virtual bool isTextureValid(FurnaceGUITexture* which);
|
||||
virtual bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
|
||||
virtual bool unlockTexture(FurnaceGUITexture* which);
|
||||
virtual bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
|
||||
virtual FurnaceGUITexture* createTexture(bool dynamic, int width, int height);
|
||||
virtual FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true, FurnaceGUITextureFormat format=GUI_TEXFORMAT_ABGR32);
|
||||
virtual bool destroyTexture(FurnaceGUITexture* which);
|
||||
virtual void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
|
||||
virtual void setBlendMode(FurnaceGUIBlendMode mode);
|
||||
virtual void resized(const SDL_Event& ev);
|
||||
virtual void clear(ImVec4 color);
|
||||
virtual bool newFrame();
|
||||
virtual bool canVSync();
|
||||
virtual void createFontsTexture();
|
||||
virtual void destroyFontsTexture();
|
||||
virtual void renderGUI();
|
||||
|
|
@ -1466,12 +1534,19 @@ class FurnaceGUIRender {
|
|||
virtual void drawOsc(float* data, size_t len, ImVec2 pos0, ImVec2 pos1, ImVec4 color, ImVec2 canvasSize, float lineWidth);
|
||||
virtual void present();
|
||||
virtual bool supportsDrawOsc();
|
||||
virtual const char* getStupidFragment();
|
||||
virtual bool regenOscShader(const char* fragment);
|
||||
virtual bool areTexturesSquare();
|
||||
virtual bool getOutputSize(int& w, int& h);
|
||||
virtual int getWindowFlags();
|
||||
virtual void preInit();
|
||||
virtual bool init(SDL_Window* win);
|
||||
virtual int getMaxTextureWidth();
|
||||
virtual int getMaxTextureHeight();
|
||||
virtual unsigned int getTextureFormats();
|
||||
virtual const char* getBackendName();
|
||||
virtual const char* getVendorName();
|
||||
virtual const char* getDeviceName();
|
||||
virtual const char* getAPIVersion();
|
||||
virtual void setSwapInterval(int swapInterval);
|
||||
virtual void preInit(const DivConfig& conf);
|
||||
virtual bool init(SDL_Window* win, int swapInterval);
|
||||
virtual void initGUI(SDL_Window* win);
|
||||
virtual void quitGUI();
|
||||
virtual bool quit();
|
||||
|
|
@ -1497,31 +1572,39 @@ struct PendingDrawOsc {
|
|||
lineSize(0.0f) {}
|
||||
};
|
||||
|
||||
struct FurnaceCV;
|
||||
|
||||
class FurnaceGUI {
|
||||
DivEngine* e;
|
||||
|
||||
FurnaceGUIRenderBackend renderBackend;
|
||||
FurnaceGUIRender* rend;
|
||||
FurnaceGUITextureFormat bestTexFormat;
|
||||
|
||||
SDL_Window* sdlWin;
|
||||
SDL_Haptic* vibrator;
|
||||
bool vibratorAvailable;
|
||||
|
||||
|
||||
FurnaceCV* cv;
|
||||
FurnaceGUITexture* cvTex;
|
||||
|
||||
FurnaceGUITexture* sampleTex;
|
||||
int sampleTexW, sampleTexH;
|
||||
bool updateSampleTex;
|
||||
|
||||
String newOscFragment;
|
||||
String workingDir, fileName, clipboard, warnString, errorString, lastError, curFileName, nextFile, sysSearchQuery, newSongQuery, paletteQuery;
|
||||
String workingDir, fileName, clipboard, warnString, errorString, lastError, curFileName, nextFile, sysSearchQuery, newSongQuery, paletteQuery, sampleBankSearchQuery;
|
||||
String workingDirSong, workingDirIns, workingDirWave, workingDirSample, workingDirAudioExport;
|
||||
String workingDirVGMExport, workingDirZSMExport, workingDirROMExport, workingDirFont, workingDirColors, workingDirKeybinds;
|
||||
String workingDirVGMExport, workingDirZSMExport, workingDirROMExport;
|
||||
String workingDirFont, workingDirColors, workingDirKeybinds;
|
||||
String workingDirLayout, workingDirROM, workingDirTest;
|
||||
String workingDirConfig;
|
||||
String mmlString[32];
|
||||
String mmlStringW, grooveString, grooveListString, mmlStringModTable;
|
||||
String mmlStringSNES[DIV_MAX_CHIPS];
|
||||
String folderString;
|
||||
|
||||
std::vector<DivSystem> sysSearchResults;
|
||||
std::vector<std::pair<DivSample*,bool>> sampleBankSearchResults;
|
||||
std::vector<FurnaceGUISysDef> newSongSearchResults;
|
||||
std::vector<int> paletteSearchResults;
|
||||
FixedQueue<String,32> recentFile;
|
||||
|
|
@ -1534,9 +1617,12 @@ class FurnaceGUI {
|
|||
bool vgmExportDirectStream, displayInsTypeList, displayWaveSizeList;
|
||||
bool portrait, injectBackUp, mobileMenuOpen, warnColorPushed;
|
||||
bool wantCaptureKeyboard, oldWantCaptureKeyboard, displayMacroMenu;
|
||||
bool displayNew, displayExport, displayPalette, fullScreen, preserveChanPos, sysDupCloneChannels, sysDupEnd, wantScrollList, noteInputPoly, notifyWaveChange;
|
||||
bool displayNew, displayExport, displayPalette, fullScreen, preserveChanPos, sysDupCloneChannels, sysDupEnd, noteInputPoly, notifyWaveChange;
|
||||
bool wantScrollListIns, wantScrollListWave, wantScrollListSample;
|
||||
bool displayPendingIns, pendingInsSingle, displayPendingRawSample, snesFilterHex, modTableHex, displayEditString;
|
||||
bool shaderEditor;
|
||||
bool displayPendingSamples, replacePendingSample;
|
||||
bool displayExportingROM;
|
||||
bool changeCoarse;
|
||||
bool mobileEdit;
|
||||
bool killGraphics;
|
||||
bool safeMode;
|
||||
|
|
@ -1546,6 +1632,7 @@ class FurnaceGUI {
|
|||
bool willExport[DIV_MAX_CHIPS];
|
||||
int vgmExportVersion;
|
||||
int vgmExportTrailingTicks;
|
||||
int cvHiScore;
|
||||
int drawHalt;
|
||||
int zsmExportTickRate;
|
||||
int macroPointSize;
|
||||
|
|
@ -1601,6 +1688,12 @@ class FurnaceGUI {
|
|||
std::mutex backupLock;
|
||||
String backupPath;
|
||||
|
||||
std::vector<FurnaceGUIBackupEntry> backupEntries;
|
||||
std::future<bool> backupEntryTask;
|
||||
std::mutex backupEntryLock;
|
||||
uint64_t totalBackupSize;
|
||||
bool refreshBackups;
|
||||
|
||||
std::mutex midiLock;
|
||||
FixedQueue<TAMidiMessage,4096> midiQueue;
|
||||
MIDIMap midiMap;
|
||||
|
|
@ -1613,6 +1706,7 @@ class FurnaceGUI {
|
|||
ImFont* bigFont;
|
||||
ImFont* headFont;
|
||||
ImWchar* fontRange;
|
||||
ImWchar* fontRangeB;
|
||||
ImVec4 uiColors[GUI_COLOR_MAX];
|
||||
ImVec4 volColors[128];
|
||||
ImU32 pitchGrad[256];
|
||||
|
|
@ -1643,10 +1737,25 @@ class FurnaceGUI {
|
|||
int fdsCore;
|
||||
int c64Core;
|
||||
int pokeyCore;
|
||||
int opnCore;
|
||||
int opn1Core;
|
||||
int opnaCore;
|
||||
int opnbCore;
|
||||
int opl2Core;
|
||||
int opl3Core;
|
||||
int esfmCore;
|
||||
int opllCore;
|
||||
int ayCore;
|
||||
int bubsysQuality;
|
||||
int dsidQuality;
|
||||
int gbQuality;
|
||||
int ndsQuality;
|
||||
int pceQuality;
|
||||
int pnQuality;
|
||||
int saaQuality;
|
||||
int sccQuality;
|
||||
int smQuality;
|
||||
int swanQuality;
|
||||
int vbQuality;
|
||||
int arcadeCoreRender;
|
||||
int ym2612CoreRender;
|
||||
int snCoreRender;
|
||||
|
|
@ -1654,10 +1763,25 @@ class FurnaceGUI {
|
|||
int fdsCoreRender;
|
||||
int c64CoreRender;
|
||||
int pokeyCoreRender;
|
||||
int opnCoreRender;
|
||||
int opn1CoreRender;
|
||||
int opnaCoreRender;
|
||||
int opnbCoreRender;
|
||||
int opl2CoreRender;
|
||||
int opl3CoreRender;
|
||||
int esfmCoreRender;
|
||||
int opllCoreRender;
|
||||
int ayCoreRender;
|
||||
int bubsysQualityRender;
|
||||
int dsidQualityRender;
|
||||
int gbQualityRender;
|
||||
int ndsQualityRender;
|
||||
int pceQualityRender;
|
||||
int pnQualityRender;
|
||||
int saaQualityRender;
|
||||
int sccQualityRender;
|
||||
int smQualityRender;
|
||||
int swanQualityRender;
|
||||
int vbQualityRender;
|
||||
int pcSpeakerOutMethod;
|
||||
String yrw801Path;
|
||||
String tg100Path;
|
||||
|
|
@ -1705,6 +1829,7 @@ class FurnaceGUI {
|
|||
int loadChinese;
|
||||
int loadChineseTraditional;
|
||||
int loadKorean;
|
||||
int loadFallback;
|
||||
int fmLayout;
|
||||
int sampleLayout;
|
||||
int waveLayout;
|
||||
|
|
@ -1802,7 +1927,6 @@ class FurnaceGUI {
|
|||
int wasapiEx;
|
||||
int chanOscThreads;
|
||||
int renderPoolThreads;
|
||||
int showPool;
|
||||
int writeInsNames;
|
||||
int readInsNames;
|
||||
int fontBackend;
|
||||
|
|
@ -1810,14 +1934,35 @@ class FurnaceGUI {
|
|||
int fontBitmap;
|
||||
int fontAutoHint;
|
||||
int fontAntiAlias;
|
||||
int fontOversample;
|
||||
int selectAssetOnLoad;
|
||||
int basicColors;
|
||||
int playbackTime;
|
||||
int shaderOsc;
|
||||
int cursorWheelStep;
|
||||
int vsync;
|
||||
int frameRateLimit;
|
||||
int displayRenderTime;
|
||||
int inputRepeat;
|
||||
int glRedSize;
|
||||
int glGreenSize;
|
||||
int glBlueSize;
|
||||
int glAlphaSize;
|
||||
int glDepthSize;
|
||||
int glStencilSize;
|
||||
int glBufferSize;
|
||||
int glDoubleBuffer;
|
||||
int backupEnable;
|
||||
int backupInterval;
|
||||
int backupMaxCopies;
|
||||
int autoFillSave;
|
||||
int autoMacroStepSize;
|
||||
unsigned int maxUndoSteps;
|
||||
float vibrationStrength;
|
||||
int vibrationLength;
|
||||
int s3mOPL3;
|
||||
int chipManagerTooltip;
|
||||
int sysTooltipChanInfoStyle;
|
||||
unsigned int maxUndoSteps;
|
||||
String mainFontPath;
|
||||
String headFontPath;
|
||||
String patFontPath;
|
||||
|
|
@ -1834,14 +1979,15 @@ class FurnaceGUI {
|
|||
String emptyLabel2;
|
||||
String sdlAudioDriver;
|
||||
String defaultAuthorName;
|
||||
String locale;
|
||||
DivConfig initialSys;
|
||||
|
||||
Settings():
|
||||
settingsChanged(false),
|
||||
mainFontSize(18),
|
||||
patFontSize(18),
|
||||
mainFontSize(GUI_FONT_SIZE_DEFAULT),
|
||||
patFontSize(GUI_FONT_SIZE_DEFAULT),
|
||||
headFontSize(27),
|
||||
iconSize(16),
|
||||
iconSize(GUI_ICON_SIZE_DEFAULT),
|
||||
audioEngine(DIV_AUDIO_SDL),
|
||||
audioQuality(0),
|
||||
audioHiPass(1),
|
||||
|
|
@ -1853,10 +1999,25 @@ class FurnaceGUI {
|
|||
fdsCore(0),
|
||||
c64Core(0),
|
||||
pokeyCore(1),
|
||||
opnCore(1),
|
||||
opn1Core(1),
|
||||
opnaCore(1),
|
||||
opnbCore(1),
|
||||
opl2Core(0),
|
||||
opl3Core(0),
|
||||
esfmCore(0),
|
||||
opllCore(0),
|
||||
ayCore(0),
|
||||
bubsysQuality(3),
|
||||
dsidQuality(3),
|
||||
gbQuality(3),
|
||||
ndsQuality(3),
|
||||
pceQuality(3),
|
||||
pnQuality(3),
|
||||
saaQuality(3),
|
||||
sccQuality(3),
|
||||
smQuality(3),
|
||||
swanQuality(3),
|
||||
vbQuality(3),
|
||||
arcadeCoreRender(1),
|
||||
ym2612CoreRender(0),
|
||||
snCoreRender(0),
|
||||
|
|
@ -1864,10 +2025,25 @@ class FurnaceGUI {
|
|||
fdsCoreRender(1),
|
||||
c64CoreRender(1),
|
||||
pokeyCoreRender(1),
|
||||
opnCoreRender(1),
|
||||
opn1CoreRender(1),
|
||||
opnaCoreRender(1),
|
||||
opnbCoreRender(1),
|
||||
opl2CoreRender(0),
|
||||
opl3CoreRender(0),
|
||||
esfmCoreRender(0),
|
||||
opllCoreRender(0),
|
||||
ayCoreRender(0),
|
||||
bubsysQualityRender(3),
|
||||
dsidQualityRender(3),
|
||||
gbQualityRender(3),
|
||||
ndsQualityRender(3),
|
||||
pceQualityRender(3),
|
||||
pnQualityRender(3),
|
||||
saaQualityRender(3),
|
||||
sccQualityRender(3),
|
||||
smQualityRender(3),
|
||||
swanQualityRender(3),
|
||||
vbQualityRender(3),
|
||||
pcSpeakerOutMethod(0),
|
||||
yrw801Path(""),
|
||||
tg100Path(""),
|
||||
|
|
@ -1913,6 +2089,7 @@ class FurnaceGUI {
|
|||
loadChinese(0),
|
||||
loadChineseTraditional(0),
|
||||
loadKorean(0),
|
||||
loadFallback(1),
|
||||
fmLayout(4),
|
||||
sampleLayout(0),
|
||||
waveLayout(0),
|
||||
|
|
@ -2009,7 +2186,6 @@ class FurnaceGUI {
|
|||
wasapiEx(0),
|
||||
chanOscThreads(0),
|
||||
renderPoolThreads(0),
|
||||
showPool(0),
|
||||
writeInsNames(0),
|
||||
readInsNames(1),
|
||||
fontBackend(1),
|
||||
|
|
@ -2017,14 +2193,35 @@ class FurnaceGUI {
|
|||
fontBitmap(0),
|
||||
fontAutoHint(1),
|
||||
fontAntiAlias(1),
|
||||
fontOversample(GUI_OVERSAMPLE_DEFAULT),
|
||||
selectAssetOnLoad(1),
|
||||
basicColors(1),
|
||||
playbackTime(1),
|
||||
shaderOsc(1),
|
||||
cursorWheelStep(0),
|
||||
vsync(1),
|
||||
frameRateLimit(60),
|
||||
displayRenderTime(0),
|
||||
inputRepeat(0),
|
||||
glRedSize(8),
|
||||
glGreenSize(8),
|
||||
glBlueSize(8),
|
||||
glAlphaSize(0),
|
||||
glDepthSize(24),
|
||||
glStencilSize(0),
|
||||
glBufferSize(32),
|
||||
glDoubleBuffer(1),
|
||||
backupEnable(1),
|
||||
backupInterval(30),
|
||||
backupMaxCopies(5),
|
||||
autoFillSave(0),
|
||||
autoMacroStepSize(0),
|
||||
maxUndoSteps(100),
|
||||
vibrationStrength(0.5f),
|
||||
vibrationLength(20),
|
||||
s3mOPL3(1),
|
||||
chipManagerTooltip(1), // poll?
|
||||
sysTooltipChanInfoStyle(3), // poll?
|
||||
maxUndoSteps(100),
|
||||
mainFontPath(""),
|
||||
headFontPath(""),
|
||||
patFontPath(""),
|
||||
|
|
@ -2040,24 +2237,31 @@ class FurnaceGUI {
|
|||
emptyLabel("..."),
|
||||
emptyLabel2(".."),
|
||||
sdlAudioDriver(""),
|
||||
defaultAuthorName("") {}
|
||||
defaultAuthorName(""),
|
||||
locale("") {}
|
||||
} settings;
|
||||
|
||||
struct Tutorial {
|
||||
int userComesFrom;
|
||||
bool introPlayed;
|
||||
bool protoWelcome;
|
||||
bool taken[GUI_TUTORIAL_MAX];
|
||||
Tutorial():
|
||||
userComesFrom(0),
|
||||
#ifdef SUPPORT_XP
|
||||
introPlayed(true),
|
||||
#else
|
||||
introPlayed(false),
|
||||
#endif
|
||||
protoWelcome(false) {
|
||||
memset(taken,0,GUI_TUTORIAL_MAX*sizeof(bool));
|
||||
}
|
||||
} tutorial;
|
||||
|
||||
char finalLayoutPath[4096];
|
||||
|
||||
bool localeRequiresJapanese;
|
||||
bool localeRequiresChinese;
|
||||
bool localeRequiresChineseTrad;
|
||||
bool localeRequiresKorean;
|
||||
std::vector<ImWchar> localeExtraRanges;
|
||||
|
||||
DivInstrument* prevInsData;
|
||||
|
||||
unsigned char* pendingLayoutImport;
|
||||
|
|
@ -2065,14 +2269,14 @@ class FurnaceGUI {
|
|||
int pendingLayoutImportStep;
|
||||
FixedQueue<bool*,64> pendingLayoutImportReopen;
|
||||
|
||||
int curIns, curWave, curSample, curOctave, curOrder, playOrder, prevIns, oldRow, editStep, exportLoops, soloChan, orderEditMode, orderCursor;
|
||||
int curIns, curWave, curSample, curOctave, curOrder, playOrder, prevIns, oldRow, editStep, editStepCoarse, soloChan, orderEditMode, orderCursor;
|
||||
int loopOrder, loopRow, loopEnd, isClipping, newSongCategory, latchTarget;
|
||||
int wheelX, wheelY, dragSourceX, dragSourceXFine, dragSourceY, dragDestinationX, dragDestinationXFine, dragDestinationY, oldBeat, oldBar;
|
||||
int curGroove, exitDisabledTimer;
|
||||
int curPaletteChoice, curPaletteType;
|
||||
float soloTimeout;
|
||||
|
||||
double exportFadeOut;
|
||||
int purgeYear, purgeMonth, purgeDay;
|
||||
|
||||
bool patExtraButtons, patChannelNames, patChannelPairs;
|
||||
unsigned char patChannelHints;
|
||||
|
|
@ -2083,7 +2287,9 @@ class FurnaceGUI {
|
|||
bool mixerOpen, debugOpen, inspectorOpen, oscOpen, volMeterOpen, statsOpen, compatFlagsOpen;
|
||||
bool pianoOpen, notesOpen, channelsOpen, regViewOpen, logOpen, effectListOpen, chanOscOpen;
|
||||
bool subSongsOpen, findOpen, spoilerOpen, patManagerOpen, sysManagerOpen, clockOpen, speedOpen;
|
||||
bool groovesOpen, xyOscOpen, memoryOpen, csPlayerOpen;
|
||||
bool groovesOpen, xyOscOpen, memoryOpen, csPlayerOpen, cvOpen, userPresetsOpen;
|
||||
|
||||
bool cvNotSerious;
|
||||
|
||||
bool shortIntro;
|
||||
bool insListDir, waveListDir, sampleListDir;
|
||||
|
|
@ -2172,9 +2378,11 @@ class FurnaceGUI {
|
|||
std::vector<DivCommand> cmdStream;
|
||||
std::vector<Particle> particles;
|
||||
std::vector<std::pair<DivInstrument*,bool>> pendingIns;
|
||||
std::vector<std::pair<DivSample*,bool>> pendingSamples;
|
||||
|
||||
std::vector<FurnaceGUISysCategory> sysCategories;
|
||||
FurnaceGUITutorialDef tutorials[GUI_TUTORIAL_MAX];
|
||||
|
||||
std::vector<String> audioLoadFormats;
|
||||
|
||||
bool wavePreviewOn;
|
||||
SDL_Scancode wavePreviewKey;
|
||||
|
|
@ -2253,6 +2461,7 @@ class FurnaceGUI {
|
|||
uint64_t drawTimeBegin, drawTimeEnd, drawTimeDelta;
|
||||
uint64_t swapTimeBegin, swapTimeEnd, swapTimeDelta;
|
||||
uint64_t eventTimeBegin, eventTimeEnd, eventTimeDelta;
|
||||
uint64_t nextPresentTime;
|
||||
|
||||
FurnaceGUIPerfMetric perfMetrics[64];
|
||||
int perfMetricsLen;
|
||||
|
|
@ -2271,7 +2480,7 @@ class FurnaceGUI {
|
|||
ImVec2 fourChars, threeChars, twoChars;
|
||||
ImVec2 noteCellSize, insCellSize, volCellSize, effectCellSize, effectValCellSize;
|
||||
SelectionPoint sel1, sel2;
|
||||
int dummyRows, demandX;
|
||||
int dummyRows;
|
||||
int transposeAmount, randomizeMin, randomizeMax, fadeMin, fadeMax, collapseAmount;
|
||||
float scaleMax;
|
||||
bool fadeMode, randomMode, haveHitBounds;
|
||||
|
|
@ -2472,14 +2681,30 @@ class FurnaceGUI {
|
|||
ImGuiListClipper csClipper;
|
||||
|
||||
// export options
|
||||
int audioExportType;
|
||||
DivAudioExportOptions audioExportOptions;
|
||||
int dmfExportVersion;
|
||||
FurnaceGUIExportTypes curExportType;
|
||||
|
||||
// ROM export specific
|
||||
DivROMExportOptions romTarget;
|
||||
DivConfig romConfig;
|
||||
bool romMultiFile;
|
||||
bool romExportSave;
|
||||
String romFilterName, romFilterExt;
|
||||
String romExportPath;
|
||||
DivROMExport* pendingExport;
|
||||
bool romExportAvail[DIV_ROM_MAX];
|
||||
bool romExportExists;
|
||||
|
||||
// user presets window
|
||||
std::vector<int> selectedUserPreset;
|
||||
|
||||
std::vector<String> randomDemoSong;
|
||||
|
||||
void drawExportAudio(bool onWindow=false);
|
||||
void drawExportVGM(bool onWindow=false);
|
||||
void drawExportROM(bool onWindow=false);
|
||||
void drawExportZSM(bool onWindow=false);
|
||||
void drawExportAmigaVal(bool onWindow=false);
|
||||
void drawExportText(bool onWindow=false);
|
||||
void drawExportCommand(bool onWindow=false);
|
||||
void drawExportDMF(bool onWindow=false);
|
||||
|
|
@ -2501,6 +2726,9 @@ class FurnaceGUI {
|
|||
void renderFMPreviewOPZ(const DivInstrumentFM& params, int pos=0);
|
||||
void renderFMPreviewESFM(const DivInstrumentFM& params, const DivInstrumentESFM& esfmParams, int pos=0);
|
||||
|
||||
// combo with locale
|
||||
static bool LocalizedComboGetter(void* data, int idx, const char** out_text);
|
||||
|
||||
// these ones offer ctrl-wheel fine value changes.
|
||||
bool CWSliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format=NULL, ImGuiSliderFlags flags=0);
|
||||
bool CWVSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format=NULL, ImGuiSliderFlags flags=0);
|
||||
|
|
@ -2516,6 +2744,7 @@ class FurnaceGUI {
|
|||
bool portSet(String label, unsigned int portSetID, int ins, int outs, int activeIns, int activeOuts, int& clickedPort, std::map<unsigned int,ImVec2>& portPos);
|
||||
|
||||
void updateWindowTitle();
|
||||
void updateROMExportAvail();
|
||||
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();
|
||||
|
|
@ -2545,6 +2774,8 @@ class FurnaceGUI {
|
|||
void drawMacros(std::vector<FurnaceGUIMacroDesc>& macros, FurnaceGUIMacroEditState& state);
|
||||
void alterSampleMap(int column, int val);
|
||||
|
||||
void insTabFMModernHeader(DivInstrument* ins);
|
||||
void insTabFM(DivInstrument* ins);
|
||||
void insTabSample(DivInstrument* ins);
|
||||
|
||||
void drawOrderButtons();
|
||||
|
|
@ -2556,7 +2787,9 @@ 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 drawSysDefs(std::vector<FurnaceGUISysDef>& category, bool& accepted, std::vector<int>& sysDefStack, bool& alreadyHover);
|
||||
void printPresets(std::vector<FurnaceGUISysDef>& items, size_t depth, std::vector<int>& depthStack);
|
||||
FurnaceGUISysDef* selectPreset(std::vector<FurnaceGUISysDef>& items);
|
||||
|
||||
void toggleMobileUI(bool enable, bool force=false);
|
||||
|
||||
|
|
@ -2612,6 +2845,7 @@ class FurnaceGUI {
|
|||
void drawClock();
|
||||
void drawTutorial();
|
||||
void drawXYOsc();
|
||||
void drawUserPresets();
|
||||
void drawSystemChannelInfo(const DivSysDef* whichDef);
|
||||
void drawSystemChannelInfoText(const DivSysDef* whichDef);
|
||||
|
||||
|
|
@ -2625,12 +2859,17 @@ class FurnaceGUI {
|
|||
bool exportKeybinds(String path);
|
||||
bool importLayout(String path);
|
||||
bool exportLayout(String path);
|
||||
bool importConfig(String path);
|
||||
bool exportConfig(String path);
|
||||
|
||||
float computeGradPos(int type, int chan);
|
||||
|
||||
void resetColors();
|
||||
void resetKeybinds();
|
||||
|
||||
bool splitBackupName(const char* input, String& backupName, struct tm& backupTime);
|
||||
void purgeBackups(int year, int month, int day);
|
||||
|
||||
void readConfig(DivConfig& conf, FurnaceGUISettingGroups groups=GUI_SETTINGS_ALL);
|
||||
void writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups=GUI_SETTINGS_ALL);
|
||||
|
||||
|
|
@ -2638,7 +2877,8 @@ class FurnaceGUI {
|
|||
void commitSettings();
|
||||
void syncTutorial();
|
||||
void commitTutorial();
|
||||
void commitState();
|
||||
void syncState();
|
||||
void commitState(DivConfig& conf);
|
||||
void processDrags(int dragX, int dragY);
|
||||
void processPoint(SDL_Event& ev);
|
||||
|
||||
|
|
@ -2659,6 +2899,7 @@ class FurnaceGUI {
|
|||
void doDelete();
|
||||
void doPullDelete();
|
||||
void doInsert();
|
||||
void moveSelected(int x, int y);
|
||||
void doTranspose(int amount, OperationMask& mask);
|
||||
String doCopy(bool cut, bool writeClipboard, const SelectionPoint& sStart, const SelectionPoint& sEnd);
|
||||
void doPasteFurnace(PasteMode mode, int arg, bool readClipboard, String clipb, std::vector<String> data, int startOff, bool invalidData, UndoRegion ur);
|
||||
|
|
@ -2720,11 +2961,12 @@ class FurnaceGUI {
|
|||
|
||||
void applyUISettings(bool updateFonts=true);
|
||||
void initSystemPresets();
|
||||
void initTutorial();
|
||||
void activateTutorial(FurnaceGUITutorials which);
|
||||
|
||||
bool loadUserPresets(bool redundancy=true);
|
||||
bool saveUserPresets(bool redundancy=true);
|
||||
void initRandomDemoSong();
|
||||
bool loadRandomDemoSong();
|
||||
|
||||
bool loadUserPresets(bool redundancy=true, String path="", bool append=false);
|
||||
bool saveUserPresets(bool redundancy=true, String path="");
|
||||
|
||||
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);
|
||||
|
|
@ -2736,6 +2978,8 @@ class FurnaceGUI {
|
|||
bool initRender();
|
||||
bool quitRender();
|
||||
|
||||
ImFont* addFontZlib(const void* data, size_t len, float size_pixels, const ImFontConfig* font_cfg=NULL, const ImWchar* glyph_ranges=NULL);
|
||||
|
||||
const char* getSystemName(DivSystem which);
|
||||
const char* getSystemPartNumber(DivSystem sys, DivConfig& flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ const char* insTypes[DIV_INS_MAX+1][3]={
|
|||
{"FM (OPN)",ICON_FA_AREA_CHART,ICON_FUR_INS_FM},
|
||||
{"Game Boy",ICON_FA_GAMEPAD,ICON_FUR_INS_GB},
|
||||
{"C64",ICON_FA_KEYBOARD_O,ICON_FUR_INS_C64},
|
||||
{"Generic Sample",ICON_FA_VOLUME_UP,ICON_FUR_INS_AMIGA},
|
||||
{_N("Generic Sample"),ICON_FA_VOLUME_UP,ICON_FUR_INS_AMIGA},
|
||||
{"PC Engine",ICON_FA_ID_BADGE,ICON_FUR_INS_PCE},
|
||||
{"AY-3-8910/SSG",ICON_FA_BAR_CHART,ICON_FUR_INS_AY},
|
||||
{"AY8930",ICON_FA_BAR_CHART,ICON_FUR_INS_AY8930},
|
||||
|
|
@ -146,13 +146,13 @@ const char* insTypes[DIV_INS_MAX+1][3]={
|
|||
{"Atari Lynx",ICON_FA_BAR_CHART,ICON_FUR_INS_MIKEY},
|
||||
{"VERA",ICON_FA_KEYBOARD_O,ICON_FUR_INS_VERA},
|
||||
{"X1-010",ICON_FA_BAR_CHART,ICON_FUR_INS_X1_010},
|
||||
{"VRC6 (saw)",ICON_FA_BAR_CHART,ICON_FUR_INS_VRC6_SAW},
|
||||
{_("VRC6 (saw)"),ICON_FA_BAR_CHART,ICON_FUR_INS_VRC6_SAW},
|
||||
{"ES5506",ICON_FA_VOLUME_UP,ICON_FUR_INS_ES5506},
|
||||
{"MultiPCM",ICON_FA_VOLUME_UP,ICON_FUR_INS_MULTIPCM},
|
||||
{"SNES",ICON_FA_VOLUME_UP,ICON_FUR_INS_SNES},
|
||||
{"Sound Unit",ICON_FA_MICROCHIP,ICON_FUR_INS_SU},
|
||||
{"Namco WSG",ICON_FA_PIE_CHART,ICON_FUR_INS_NAMCO},
|
||||
{"OPL (drums)",ICON_FA_COFFEE,ICON_FUR_INS_OPL_DRUMS},
|
||||
{_N("OPL (drums)"),ICON_FA_COFFEE,ICON_FUR_INS_OPL_DRUMS},
|
||||
{"FM (OPM)",ICON_FA_AREA_CHART,ICON_FUR_INS_OPM},
|
||||
{"NES",ICON_FA_GAMEPAD,ICON_FUR_INS_NES},
|
||||
{"MSM6258",ICON_FA_VOLUME_UP,ICON_FUR_INS_MSM6258},
|
||||
|
|
@ -176,19 +176,21 @@ const char* insTypes[DIV_INS_MAX+1][3]={
|
|||
{"C140",ICON_FA_VOLUME_UP,ICON_FUR_INS_C140},
|
||||
{"C219",ICON_FA_VOLUME_UP,ICON_FUR_INS_C219},
|
||||
{"FM (ESFM)",ICON_FA_AREA_CHART,ICON_FUR_INS_ESFM},
|
||||
{"PowerNoise (noise)",ICON_FUR_NOISE,ICON_FUR_INS_POWERNOISE},
|
||||
{"PowerNoise (slope)",ICON_FUR_SAW,ICON_FUR_INS_POWERNOISE_SAW},
|
||||
{_N("PowerNoise (noise)"),ICON_FUR_NOISE,ICON_FUR_INS_POWERNOISE},
|
||||
{_N("PowerNoise (slope)"),ICON_FUR_SAW,ICON_FUR_INS_POWERNOISE_SAW},
|
||||
{"Dave",ICON_FA_BAR_CHART,ICON_FUR_INS_DAVE},
|
||||
{"Nintendo DS",ICON_FA_BAR_CHART,ICON_FUR_INS_NDS},
|
||||
{"GBA DMA",ICON_FA_GAMEPAD,ICON_FUR_INS_GBA_DMA},
|
||||
{"GBA MinMod",ICON_FA_VOLUME_UP,ICON_FUR_INS_GBA_MINMOD},
|
||||
{"Bifurcator",ICON_FA_LINE_CHART,ICON_FUR_INS_BIFURCATOR},
|
||||
{"SID2",ICON_FA_KEYBOARD_O,ICON_FUR_INS_SID2},
|
||||
{NULL,ICON_FA_QUESTION,ICON_FA_QUESTION}
|
||||
};
|
||||
|
||||
const char* sampleLoopModes[DIV_SAMPLE_LOOP_MAX]={
|
||||
"Forward",
|
||||
"Backward",
|
||||
"Ping pong"
|
||||
_N("Forward"),
|
||||
_N("Backward"),
|
||||
_N("Ping pong")
|
||||
};
|
||||
|
||||
const char* sampleDepths[DIV_SAMPLE_DEPTH_MAX]={
|
||||
|
|
@ -212,25 +214,25 @@ const char* sampleDepths[DIV_SAMPLE_DEPTH_MAX]={
|
|||
};
|
||||
|
||||
const char* resampleStrats[]={
|
||||
"none",
|
||||
"linear",
|
||||
"cubic spline",
|
||||
"blep synthesis",
|
||||
"sinc",
|
||||
"best possible"
|
||||
_N("none"),
|
||||
_N("linear"),
|
||||
_N("cubic spline"),
|
||||
_N("blep synthesis"),
|
||||
_N("sinc"),
|
||||
_N("best possible")
|
||||
};
|
||||
|
||||
const char* fxColorsNames[]={
|
||||
"Invalid",
|
||||
"Pitch",
|
||||
"Volume",
|
||||
"Panning",
|
||||
"Song",
|
||||
"Time",
|
||||
"Speed",
|
||||
"System (Primary)",
|
||||
"System (Secondary)",
|
||||
"Miscellaneous"
|
||||
_N("Invalid"),
|
||||
_N("Pitch"),
|
||||
_N("Volume"),
|
||||
_N("Panning"),
|
||||
_N("Song"),
|
||||
_N("Time"),
|
||||
_N("Speed"),
|
||||
_N("System (Primary)"),
|
||||
_N("System (Secondary)"),
|
||||
_N("Miscellaneous")
|
||||
};
|
||||
|
||||
const char* chanNames[]={
|
||||
|
|
@ -402,8 +404,8 @@ const FurnaceGUIColors fxColors[256]={
|
|||
GUI_COLOR_PATTERN_EFFECT_PANNING,
|
||||
GUI_COLOR_PATTERN_EFFECT_PANNING,
|
||||
GUI_COLOR_PATTERN_EFFECT_PANNING,
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_PANNING,
|
||||
GUI_COLOR_PATTERN_EFFECT_PANNING,
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
|
|
@ -501,7 +503,7 @@ const FurnaceGUIColors fxColors[256]={
|
|||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_VOLUME, // DC
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_MISC, // DF
|
||||
|
|
@ -536,8 +538,8 @@ const FurnaceGUIColors fxColors[256]={
|
|||
GUI_COLOR_PATTERN_EFFECT_VOLUME, // FA
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID, // FB
|
||||
GUI_COLOR_PATTERN_EFFECT_TIME, // FC
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID, // FD
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID, // FE
|
||||
GUI_COLOR_PATTERN_EFFECT_SPEED, // FD
|
||||
GUI_COLOR_PATTERN_EFFECT_SPEED, // FE
|
||||
GUI_COLOR_PATTERN_EFFECT_SONG // FF
|
||||
};
|
||||
|
||||
|
|
@ -546,269 +548,278 @@ const FurnaceGUIColors fxColors[256]={
|
|||
|
||||
// format: ("ACTION_ENUM", "Action name", defaultBind)
|
||||
const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={
|
||||
D("GLOBAL_MIN", "---Global", NOT_AN_ACTION),
|
||||
D("NEW", "New", FURKMOD_CMD|SDLK_n),
|
||||
D("OPEN", "Open file", FURKMOD_CMD|SDLK_o),
|
||||
D("OPEN_BACKUP", "Restore backup", 0),
|
||||
D("SAVE", "Save file", FURKMOD_CMD|SDLK_s),
|
||||
D("SAVE_AS", "Save as", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_s),
|
||||
D("EXPORT", "Export", 0),
|
||||
D("UNDO", "Undo", FURKMOD_CMD|SDLK_z),
|
||||
D("GLOBAL_MIN", _N("---Global"), NOT_AN_ACTION),
|
||||
D("NEW", _N("New"), FURKMOD_CMD|SDLK_n),
|
||||
D("OPEN", _N("Open file"), FURKMOD_CMD|SDLK_o),
|
||||
D("OPEN_BACKUP", _N("Restore backup"), 0),
|
||||
D("SAVE", _N("Save file"), FURKMOD_CMD|SDLK_s),
|
||||
D("SAVE_AS", _N("Save as"), FURKMOD_CMD|FURKMOD_SHIFT|SDLK_s),
|
||||
D("EXPORT", _N("Export"), 0),
|
||||
D("UNDO", _N("Undo"), FURKMOD_CMD|SDLK_z),
|
||||
#ifdef __APPLE__
|
||||
D("REDO", "Redo", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_z),
|
||||
D("REDO", _N("Redo"), FURKMOD_CMD|FURKMOD_SHIFT|SDLK_z),
|
||||
#else
|
||||
D("REDO", "Redo", FURKMOD_CMD|SDLK_y),
|
||||
D("REDO", _N("Redo"), FURKMOD_CMD|SDLK_y),
|
||||
#endif
|
||||
D("QUIT", "Exit", 0),
|
||||
D("PLAY_TOGGLE", "Play/Stop (toggle)", SDLK_RETURN),
|
||||
D("PLAY", "Play", 0),
|
||||
D("STOP", "Stop", 0),
|
||||
D("PLAY_START", "Play (from beginning)", SDLK_F5),
|
||||
D("PLAY_REPEAT", "Play (repeat pattern)", 0),
|
||||
D("PLAY_CURSOR", "Play from cursor", FURKMOD_SHIFT|SDLK_RETURN),
|
||||
D("STEP_ONE", "Step row", FURKMOD_CMD|SDLK_RETURN),
|
||||
D("OCTAVE_UP", "Octave up", SDLK_KP_MULTIPLY),
|
||||
D("OCTAVE_DOWN", "Octave down", SDLK_KP_DIVIDE),
|
||||
D("INS_UP", "Previous instrument", FURKMOD_SHIFT|SDLK_KP_DIVIDE),
|
||||
D("INS_DOWN", "Next instrument", FURKMOD_SHIFT|SDLK_KP_MULTIPLY),
|
||||
D("STEP_UP", "Increase edit step", FURKMOD_CMD|SDLK_KP_MULTIPLY),
|
||||
D("STEP_DOWN", "Decrease edit step", FURKMOD_CMD|SDLK_KP_DIVIDE),
|
||||
D("TOGGLE_EDIT", "Toggle edit mode", SDLK_SPACE),
|
||||
D("METRONOME", "Metronome", FURKMOD_CMD|SDLK_m),
|
||||
D("REPEAT_PATTERN", "Toggle repeat pattern", 0),
|
||||
D("FOLLOW_ORDERS", "Follow orders", 0),
|
||||
D("FOLLOW_PATTERN", "Follow pattern", 0),
|
||||
D("FULLSCREEN", "Toggle full-screen", SDLK_F11),
|
||||
D("TX81Z_REQUEST", "Request voice from TX81Z", 0),
|
||||
D("PANIC", "Panic", SDLK_F12),
|
||||
D("CLEAR", "Clear song data", 0),
|
||||
D("QUIT", _N("Exit"), 0),
|
||||
D("PLAY_TOGGLE", _N("Play/Stop (toggle)"), SDLK_RETURN),
|
||||
D("PLAY", _N("Play"), 0),
|
||||
D("STOP", _N("Stop"), 0),
|
||||
D("PLAY_START", _N("Play (from beginning)"), SDLK_F5),
|
||||
D("PLAY_REPEAT", _N("Play (repeat pattern)"), 0),
|
||||
D("PLAY_CURSOR", _N("Play from cursor"), FURKMOD_SHIFT|SDLK_RETURN),
|
||||
D("STEP_ONE", _N("Step row"), FURKMOD_CMD|SDLK_RETURN),
|
||||
D("OCTAVE_UP", _N("Octave up"), SDLK_KP_MULTIPLY),
|
||||
D("OCTAVE_DOWN", _N("Octave down"), SDLK_KP_DIVIDE),
|
||||
D("INS_UP", _N("Previous instrument"), FURKMOD_SHIFT|SDLK_KP_DIVIDE),
|
||||
D("INS_DOWN", _N("Next instrument"), FURKMOD_SHIFT|SDLK_KP_MULTIPLY),
|
||||
D("STEP_UP", _N("Increase edit step"), FURKMOD_CMD|SDLK_KP_MULTIPLY),
|
||||
D("STEP_DOWN", _N("Decrease edit step"), FURKMOD_CMD|SDLK_KP_DIVIDE),
|
||||
D("TOGGLE_EDIT", _N("Toggle edit mode"), SDLK_SPACE),
|
||||
D("METRONOME", _N("Metronome"), FURKMOD_CMD|SDLK_m),
|
||||
D("REPEAT_PATTERN", _N("Toggle repeat pattern"), 0),
|
||||
D("FOLLOW_ORDERS", _N("Follow orders"), 0),
|
||||
D("FOLLOW_PATTERN", _N("Follow pattern"), 0),
|
||||
D("FULLSCREEN", _N("Toggle full-screen"), SDLK_F11),
|
||||
D("TX81Z_REQUEST", _N("Request voice from TX81Z"), 0),
|
||||
D("PANIC", _N("Panic"), SDLK_F12),
|
||||
D("CLEAR", _N("Clear song data"), 0),
|
||||
|
||||
D("COMMAND_PALETTE", "Command Palette", FURKMOD_CMD|SDLK_p),
|
||||
D("COMMAND_PALETTE", _N("Command Palette"), FURKMOD_CMD|SDLK_p),
|
||||
D("CMDPAL_MIN", "", NOT_AN_ACTION),
|
||||
D("CMDPAL_RECENT", "Recent files (Palette)", 0),
|
||||
D("CMDPAL_INSTRUMENTS", "Instruments (Palette)", 0),
|
||||
D("CMDPAL_SAMPLES", "Samples (Palette)", 0),
|
||||
D("CMDPAL_INSTRUMENT_CHANGE", "Change instrument (Palette)", 0),
|
||||
D("CMDPAL_ADD_CHIP", "Add chip (Palette)", 0),
|
||||
D("CMDPAL_RECENT", _N("Recent files (Palette)"), 0),
|
||||
D("CMDPAL_INSTRUMENTS", _N("Instruments (Palette)"), 0),
|
||||
D("CMDPAL_SAMPLES", _N("Samples (Palette)"), 0),
|
||||
D("CMDPAL_INSTRUMENT_CHANGE", _N("Change instrument (Palette)"), 0),
|
||||
D("CMDPAL_ADD_CHIP", _N("Add chip (Palette)"), 0),
|
||||
D("CMDPAL_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("WINDOW_EDIT_CONTROLS", "Edit Controls", 0),
|
||||
D("WINDOW_ORDERS", "Orders", 0),
|
||||
D("WINDOW_INS_LIST", "Instrument List", 0),
|
||||
D("WINDOW_INS_EDIT", "Instrument Editor", 0),
|
||||
D("WINDOW_SONG_INFO", "Song Information", 0),
|
||||
D("WINDOW_SPEED", "Speed", 0),
|
||||
D("WINDOW_PATTERN", "Pattern", 0),
|
||||
D("WINDOW_WAVE_LIST", "Wavetable List", 0),
|
||||
D("WINDOW_WAVE_EDIT", "Wavetable Editor", 0),
|
||||
D("WINDOW_SAMPLE_LIST", "Sample List", 0),
|
||||
D("WINDOW_SAMPLE_EDIT", "Sample Editor", 0),
|
||||
D("WINDOW_ABOUT", "About", 0),
|
||||
D("WINDOW_EDIT_CONTROLS", _N("Edit Controls"), 0),
|
||||
D("WINDOW_ORDERS", _N("Orders"), 0),
|
||||
D("WINDOW_INS_LIST", _N("Instrument List"), 0),
|
||||
D("WINDOW_INS_EDIT", _N("Instrument Editor"), 0),
|
||||
D("WINDOW_SONG_INFO", _N("Song Information"), 0),
|
||||
D("WINDOW_SPEED", _N("Speed"), 0),
|
||||
D("WINDOW_PATTERN", _N("Pattern"), 0),
|
||||
D("WINDOW_WAVE_LIST", _N("Wavetable List"), 0),
|
||||
D("WINDOW_WAVE_EDIT", _N("Wavetable Editor"), 0),
|
||||
D("WINDOW_SAMPLE_LIST", _N("Sample List"), 0),
|
||||
D("WINDOW_SAMPLE_EDIT", _N("Sample Editor"), 0),
|
||||
D("WINDOW_ABOUT", _N("About"), 0),
|
||||
#ifdef __APPLE__
|
||||
D("WINDOW_SETTINGS", "Settings", FURKMOD_CMD|SDLK_COMMA),
|
||||
D("WINDOW_SETTINGS", _N("Settings"), FURKMOD_CMD|SDLK_COMMA),
|
||||
#else
|
||||
D("WINDOW_SETTINGS", "Settings", 0),
|
||||
D("WINDOW_SETTINGS", _N("Settings"), 0),
|
||||
#endif
|
||||
D("WINDOW_MIXER", "Mixer", 0),
|
||||
D("WINDOW_DEBUG", "Debug Menu", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_d),
|
||||
D("WINDOW_OSCILLOSCOPE", "Oscilloscope (master)", 0),
|
||||
D("WINDOW_VOL_METER", "Volume Meter", 0),
|
||||
D("WINDOW_STATS", "Statistics", 0),
|
||||
D("WINDOW_COMPAT_FLAGS", "Compatibility Flags", 0),
|
||||
D("WINDOW_PIANO", "Piano", 0),
|
||||
D("WINDOW_NOTES", "Song Comments", 0),
|
||||
D("WINDOW_CHANNELS", "Channels", 0),
|
||||
D("WINDOW_PAT_MANAGER", "Pattern Manager", 0),
|
||||
D("WINDOW_SYS_MANAGER", "Chip Manager", 0),
|
||||
D("WINDOW_REGISTER_VIEW", "Register View", 0),
|
||||
D("WINDOW_LOG", "Log Viewer", 0),
|
||||
D("WINDOW_EFFECT_LIST", "Effect List", 0),
|
||||
D("WINDOW_CHAN_OSC", "Oscilloscope (per-channel)", 0),
|
||||
D("WINDOW_SUBSONGS", "Subsongs", 0),
|
||||
D("WINDOW_FIND", "Find/Replace", FURKMOD_CMD|SDLK_f),
|
||||
D("WINDOW_CLOCK", "Clock", 0),
|
||||
D("WINDOW_GROOVES", "Grooves", 0),
|
||||
D("WINDOW_XY_OSC", "Oscilloscope (X-Y)", 0),
|
||||
D("WINDOW_MEMORY", "Memory Composition", 0),
|
||||
D("WINDOW_CS_PLAYER", "Command Stream Player", 0),
|
||||
D("WINDOW_MIXER", _N("Mixer"), 0),
|
||||
D("WINDOW_DEBUG", _N("Debug Menu"), FURKMOD_CMD|FURKMOD_SHIFT|SDLK_d),
|
||||
D("WINDOW_OSCILLOSCOPE", _N("Oscilloscope (master)"), 0),
|
||||
D("WINDOW_VOL_METER", _N("Volume Meter"), 0),
|
||||
D("WINDOW_STATS", _N("Statistics"), 0),
|
||||
D("WINDOW_COMPAT_FLAGS", _N("Compatibility Flags"), 0),
|
||||
D("WINDOW_PIANO", _N("Piano"), 0),
|
||||
D("WINDOW_NOTES", _N("Song Comments"), 0),
|
||||
D("WINDOW_CHANNELS", _N("Channels"), 0),
|
||||
D("WINDOW_PAT_MANAGER", _N("Pattern Manager"), 0),
|
||||
D("WINDOW_SYS_MANAGER", _N("Chip Manager"), 0),
|
||||
D("WINDOW_REGISTER_VIEW", _N("Register View"), 0),
|
||||
D("WINDOW_LOG", _N("Log Viewer"), 0),
|
||||
D("WINDOW_EFFECT_LIST", _N("Effect List"), 0),
|
||||
D("WINDOW_CHAN_OSC", _N("Oscilloscope (per-channel)"), 0),
|
||||
D("WINDOW_SUBSONGS", _N("Subsongs"), 0),
|
||||
D("WINDOW_FIND", _N("Find/Replace"), FURKMOD_CMD|SDLK_f),
|
||||
D("WINDOW_CLOCK", _N("Clock"), 0),
|
||||
D("WINDOW_GROOVES", _N("Grooves"), 0),
|
||||
D("WINDOW_XY_OSC", _N("Oscilloscope (X-Y)"), 0),
|
||||
D("WINDOW_MEMORY", _N("Memory Composition"), 0),
|
||||
D("WINDOW_CS_PLAYER", _N("Command Stream Player"), 0),
|
||||
D("WINDOW_USER_PRESETS", _N("User Presets"), 0),
|
||||
|
||||
D("COLLAPSE_WINDOW", "Collapse/expand current window", 0),
|
||||
D("CLOSE_WINDOW", "Close current window", FURKMOD_SHIFT|SDLK_ESCAPE),
|
||||
D("COLLAPSE_WINDOW", _N("Collapse/expand current window"), 0),
|
||||
D("CLOSE_WINDOW", _N("Close current window"), FURKMOD_SHIFT|SDLK_ESCAPE),
|
||||
D("GLOBAL_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("PAT_MIN", "---Pattern", NOT_AN_ACTION),
|
||||
D("PAT_NOTE_UP", "Transpose (+1)", FURKMOD_CMD|SDLK_F2),
|
||||
D("PAT_NOTE_DOWN", "Transpose (-1)", FURKMOD_CMD|SDLK_F1),
|
||||
D("PAT_OCTAVE_UP", "Transpose (+1 octave)", FURKMOD_CMD|SDLK_F4),
|
||||
D("PAT_OCTAVE_DOWN", "Transpose (-1 octave)", FURKMOD_CMD|SDLK_F3),
|
||||
D("PAT_VALUE_UP", "Increase values (+1)", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_F2),
|
||||
D("PAT_VALUE_DOWN", "Increase values (-1)", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_F1),
|
||||
D("PAT_VALUE_UP_COARSE", "Increase values (+16)", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_F4),
|
||||
D("PAT_VALUE_DOWN_COARSE", "Increase values (-16)", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_F3),
|
||||
D("PAT_SELECT_ALL", "Select all", FURKMOD_CMD|SDLK_a),
|
||||
D("PAT_CUT", "Cut", FURKMOD_CMD|SDLK_x),
|
||||
D("PAT_COPY", "Copy", FURKMOD_CMD|SDLK_c),
|
||||
D("PAT_PASTE", "Paste", FURKMOD_CMD|SDLK_v),
|
||||
D("PAT_PASTE_MIX", "Paste Mix (foreground)", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_v),
|
||||
D("PAT_PASTE_MIX_BG", "Paste Mix (background)", 0),
|
||||
D("PAT_PASTE_FLOOD", "Paste Flood", 0),
|
||||
D("PAT_PASTE_OVERFLOW", "Paste Overflow", 0),
|
||||
D("PAT_CURSOR_UP", "Move cursor up", SDLK_UP),
|
||||
D("PAT_CURSOR_DOWN", "Move cursor down", SDLK_DOWN),
|
||||
D("PAT_CURSOR_LEFT", "Move cursor left", SDLK_LEFT),
|
||||
D("PAT_CURSOR_RIGHT", "Move cursor right", SDLK_RIGHT),
|
||||
D("PAT_CURSOR_UP_ONE", "Move cursor up by one (override Edit Step)", FURKMOD_SHIFT|SDLK_HOME),
|
||||
D("PAT_CURSOR_DOWN_ONE", "Move cursor down by one (override Edit Step)", FURKMOD_SHIFT|SDLK_END),
|
||||
D("PAT_CURSOR_LEFT_CHANNEL", "Move cursor to previous channel", 0),
|
||||
D("PAT_CURSOR_RIGHT_CHANNEL", "Move cursor to next channel", 0),
|
||||
D("PAT_CURSOR_NEXT_CHANNEL", "Move cursor to next channel (overflow)", 0),
|
||||
D("PAT_CURSOR_PREVIOUS_CHANNEL", "Move cursor to previous channel (overflow)", 0),
|
||||
D("PAT_CURSOR_BEGIN", "Move cursor to beginning of pattern", SDLK_HOME),
|
||||
D("PAT_CURSOR_END", "Move cursor to end of pattern", SDLK_END),
|
||||
D("PAT_CURSOR_UP_COARSE", "Move cursor up (coarse)", SDLK_PAGEUP),
|
||||
D("PAT_CURSOR_DOWN_COARSE", "Move cursor down (coarse)", SDLK_PAGEDOWN),
|
||||
D("PAT_SELECTION_UP", "Expand selection upwards", FURKMOD_SHIFT|SDLK_UP),
|
||||
D("PAT_SELECTION_DOWN", "Expand selection downwards", FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("PAT_SELECTION_LEFT", "Expand selection to the left", FURKMOD_SHIFT|SDLK_LEFT),
|
||||
D("PAT_SELECTION_RIGHT", "Expand selection to the right", FURKMOD_SHIFT|SDLK_RIGHT),
|
||||
D("PAT_SELECTION_UP_ONE", "Expand selection upwards by one (override Edit Step)", 0),
|
||||
D("PAT_SELECTION_DOWN_ONE", "Expand selection downwards by one (override Edit Step)", 0),
|
||||
D("PAT_SELECTION_BEGIN", "Expand selection to beginning of pattern", 0),
|
||||
D("PAT_SELECTION_END", "Expand selection to end of pattern", 0),
|
||||
D("PAT_SELECTION_UP_COARSE", "Expand selection upwards (coarse)", FURKMOD_SHIFT|SDLK_PAGEUP),
|
||||
D("PAT_SELECTION_DOWN_COARSE", "Expand selection downwards (coarse)", FURKMOD_SHIFT|SDLK_PAGEDOWN),
|
||||
D("PAT_DELETE", "Delete", SDLK_DELETE),
|
||||
D("PAT_PULL_DELETE", "Pull delete", SDLK_BACKSPACE),
|
||||
D("PAT_INSERT", "Insert", SDLK_INSERT),
|
||||
D("PAT_MUTE_CURSOR", "Mute channel at cursor", FURKMOD_ALT|SDLK_F9),
|
||||
D("PAT_SOLO_CURSOR", "Solo channel at cursor", FURKMOD_ALT|SDLK_F10),
|
||||
D("PAT_UNMUTE_ALL", "Unmute all channels", FURKMOD_ALT|FURKMOD_SHIFT|SDLK_F9),
|
||||
D("PAT_NEXT_ORDER", "Go to next order", 0),
|
||||
D("PAT_PREV_ORDER", "Go to previous order", 0),
|
||||
D("PAT_COLLAPSE", "Collapse channel at cursor", 0),
|
||||
D("PAT_INCREASE_COLUMNS", "Increase effect columns", 0),
|
||||
D("PAT_DECREASE_COLUMNS", "Decrease effect columns", 0),
|
||||
D("PAT_INTERPOLATE", "Interpolate", 0),
|
||||
D("PAT_FADE", "Fade", 0),
|
||||
D("PAT_INVERT_VALUES", "Invert values", 0),
|
||||
D("PAT_FLIP_SELECTION", "Flip selection", 0),
|
||||
D("PAT_COLLAPSE_ROWS", "Collapse rows", 0),
|
||||
D("PAT_EXPAND_ROWS", "Expand rows", 0),
|
||||
D("PAT_COLLAPSE_PAT", "Collapse pattern", 0),
|
||||
D("PAT_EXPAND_PAT", "Expand pattern", 0),
|
||||
D("PAT_COLLAPSE_SONG", "Collapse song", 0),
|
||||
D("PAT_EXPAND_SONG", "Expand song", 0),
|
||||
D("PAT_LATCH", "Set note input latch", 0),
|
||||
D("PAT_SCROLL_MODE", "Change mobile scroll mode", 0),
|
||||
D("PAT_CLEAR_LATCH", "Clear note input latch", 0),
|
||||
D("PAT_MIN", _N("---Pattern"), NOT_AN_ACTION),
|
||||
D("PAT_NOTE_UP", _N("Transpose (+1)"), FURKMOD_CMD|SDLK_F2),
|
||||
D("PAT_NOTE_DOWN", _N("Transpose (-1)"), FURKMOD_CMD|SDLK_F1),
|
||||
D("PAT_OCTAVE_UP", _N("Transpose (+1 octave)"), FURKMOD_CMD|SDLK_F4),
|
||||
D("PAT_OCTAVE_DOWN", _N("Transpose (-1 octave)"), FURKMOD_CMD|SDLK_F3),
|
||||
D("PAT_VALUE_UP", _N("Increase values (+1)"), FURKMOD_CMD|FURKMOD_SHIFT|SDLK_F2),
|
||||
D("PAT_VALUE_DOWN", _N("Increase values (-1)"), FURKMOD_CMD|FURKMOD_SHIFT|SDLK_F1),
|
||||
D("PAT_VALUE_UP_COARSE", _N("Increase values (+16)"), FURKMOD_CMD|FURKMOD_SHIFT|SDLK_F4),
|
||||
D("PAT_VALUE_DOWN_COARSE", _N("Increase values (-16)"), FURKMOD_CMD|FURKMOD_SHIFT|SDLK_F3),
|
||||
D("PAT_SELECT_ALL", _N("Select all"), FURKMOD_CMD|SDLK_a),
|
||||
D("PAT_CUT", _N("Cut"), FURKMOD_CMD|SDLK_x),
|
||||
D("PAT_COPY", _N("Copy"), FURKMOD_CMD|SDLK_c),
|
||||
D("PAT_PASTE", _N("Paste"), FURKMOD_CMD|SDLK_v),
|
||||
D("PAT_PASTE_MIX", _N("Paste Mix (foreground)"), FURKMOD_CMD|FURKMOD_SHIFT|SDLK_v),
|
||||
D("PAT_PASTE_MIX_BG", _N("Paste Mix (background)"), 0),
|
||||
D("PAT_PASTE_FLOOD", _N("Paste Flood"), 0),
|
||||
D("PAT_PASTE_OVERFLOW", _N("Paste Overflow"), 0),
|
||||
D("PAT_CURSOR_UP", _N("Move cursor up"), SDLK_UP),
|
||||
D("PAT_CURSOR_DOWN", _N("Move cursor down"), SDLK_DOWN),
|
||||
D("PAT_CURSOR_LEFT", _N("Move cursor left"), SDLK_LEFT),
|
||||
D("PAT_CURSOR_RIGHT", _N("Move cursor right"), SDLK_RIGHT),
|
||||
D("PAT_CURSOR_UP_ONE", _N("Move cursor up by one (override Edit Step)"), FURKMOD_SHIFT|SDLK_HOME),
|
||||
D("PAT_CURSOR_DOWN_ONE", _N("Move cursor down by one (override Edit Step)"), FURKMOD_SHIFT|SDLK_END),
|
||||
D("PAT_CURSOR_LEFT_CHANNEL", _N("Move cursor to previous channel"), 0),
|
||||
D("PAT_CURSOR_RIGHT_CHANNEL", _N("Move cursor to next channel"), 0),
|
||||
D("PAT_CURSOR_NEXT_CHANNEL", _N("Move cursor to next channel (overflow)"), 0),
|
||||
D("PAT_CURSOR_PREVIOUS_CHANNEL", _N("Move cursor to previous channel (overflow)"), 0),
|
||||
D("PAT_CURSOR_BEGIN", _N("Move cursor to beginning of pattern"), SDLK_HOME),
|
||||
D("PAT_CURSOR_END", _N("Move cursor to end of pattern"), SDLK_END),
|
||||
D("PAT_CURSOR_UP_COARSE", _N("Move cursor up (coarse)"), SDLK_PAGEUP),
|
||||
D("PAT_CURSOR_DOWN_COARSE", _N("Move cursor down (coarse)"), SDLK_PAGEDOWN),
|
||||
D("PAT_SELECTION_UP", _N("Expand selection upwards"), FURKMOD_SHIFT|SDLK_UP),
|
||||
D("PAT_SELECTION_DOWN", _N("Expand selection downwards"), FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("PAT_SELECTION_LEFT", _N("Expand selection to the left"), FURKMOD_SHIFT|SDLK_LEFT),
|
||||
D("PAT_SELECTION_RIGHT", _N("Expand selection to the right"), FURKMOD_SHIFT|SDLK_RIGHT),
|
||||
D("PAT_SELECTION_UP_ONE", _N("Expand selection upwards by one (override Edit Step)"), 0),
|
||||
D("PAT_SELECTION_DOWN_ONE", _N("Expand selection downwards by one (override Edit Step)"), 0),
|
||||
D("PAT_SELECTION_BEGIN", _N("Expand selection to beginning of pattern"), 0),
|
||||
D("PAT_SELECTION_END", _N("Expand selection to end of pattern"), 0),
|
||||
D("PAT_SELECTION_UP_COARSE", _N("Expand selection upwards (coarse)"), FURKMOD_SHIFT|SDLK_PAGEUP),
|
||||
D("PAT_SELECTION_DOWN_COARSE", _N("Expand selection downwards (coarse)"), FURKMOD_SHIFT|SDLK_PAGEDOWN),
|
||||
D("PAT_MOVE_UP", _N("Move selection up"), FURKMOD_ALT|SDLK_UP),
|
||||
D("PAT_MOVE_DOWN", _N("Move selection down"), FURKMOD_ALT|SDLK_DOWN),
|
||||
D("PAT_MOVE_LEFT_CHANNEL", _N("Move selection to previous channel"), FURKMOD_ALT|SDLK_LEFT),
|
||||
D("PAT_MOVE_RIGHT_CHANNEL", _N("Move selection to next channel"), FURKMOD_ALT|SDLK_RIGHT),
|
||||
D("PAT_DELETE", _N("Delete"), SDLK_DELETE),
|
||||
D("PAT_PULL_DELETE", _N("Pull delete"), SDLK_BACKSPACE),
|
||||
D("PAT_INSERT", _N("Insert"), SDLK_INSERT),
|
||||
D("PAT_MUTE_CURSOR", _N("Mute channel at cursor"), FURKMOD_ALT|SDLK_F9),
|
||||
D("PAT_SOLO_CURSOR", _N("Solo channel at cursor"), FURKMOD_ALT|SDLK_F10),
|
||||
D("PAT_UNMUTE_ALL", _N("Unmute all channels"), FURKMOD_ALT|FURKMOD_SHIFT|SDLK_F9),
|
||||
D("PAT_NEXT_ORDER", _N("Go to next order"), 0),
|
||||
D("PAT_PREV_ORDER", _N("Go to previous order"), 0),
|
||||
D("PAT_COLLAPSE", _N("Collapse channel at cursor"), 0),
|
||||
D("PAT_INCREASE_COLUMNS", _N("Increase effect columns"), 0),
|
||||
D("PAT_DECREASE_COLUMNS", _N("Decrease effect columns"), 0),
|
||||
D("PAT_INTERPOLATE", _N("Interpolate"), 0),
|
||||
D("PAT_FADE", _N("Fade"), 0),
|
||||
D("PAT_INVERT_VALUES", _N("Invert values"), 0),
|
||||
D("PAT_FLIP_SELECTION", _N("Flip selection"), 0),
|
||||
D("PAT_COLLAPSE_ROWS", _N("Collapse rows"), 0),
|
||||
D("PAT_EXPAND_ROWS", _N("Expand rows"), 0),
|
||||
D("PAT_COLLAPSE_PAT", _N("Collapse pattern"), 0),
|
||||
D("PAT_EXPAND_PAT", _N("Expand pattern"), 0),
|
||||
D("PAT_COLLAPSE_SONG", _N("Collapse song"), 0),
|
||||
D("PAT_EXPAND_SONG", _N("Expand song"), 0),
|
||||
D("PAT_LATCH", _N("Set note input latch"), 0),
|
||||
D("PAT_SCROLL_MODE", _N("Change mobile scroll mode"), 0),
|
||||
D("PAT_CLEAR_LATCH", _N("Clear note input latch"), 0),
|
||||
D("PAT_ABSORB_INSTRUMENT", _N("Set current instrument to channel's current instrument column"), 0),
|
||||
D("PAT_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("INS_LIST_MIN", "---Instrument list", NOT_AN_ACTION),
|
||||
D("INS_LIST_ADD", "Add instrument", SDLK_INSERT),
|
||||
D("INS_LIST_DUPLICATE", "Duplicate instrument", FURKMOD_CMD|SDLK_d),
|
||||
D("INS_LIST_OPEN", "Open instrument", 0),
|
||||
D("INS_LIST_OPEN_REPLACE", "Open instrument (replace current)", 0),
|
||||
D("INS_LIST_SAVE", "Save instrument", 0),
|
||||
D("INS_LIST_SAVE_DMP", "Save instrument (.dmp)", 0),
|
||||
D("INS_LIST_MOVE_UP", "Move instrument up in list", FURKMOD_SHIFT|SDLK_UP),
|
||||
D("INS_LIST_MOVE_DOWN", "Move instrument down in list", FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("INS_LIST_DELETE", "Delete instrument", 0),
|
||||
D("INS_LIST_EDIT", "Edit instrument", FURKMOD_SHIFT|SDLK_RETURN),
|
||||
D("INS_LIST_UP", "Instrument cursor up", SDLK_UP),
|
||||
D("INS_LIST_DOWN", "Instrument cursor down", SDLK_DOWN),
|
||||
D("INS_LIST_DIR_VIEW", "Instruments: toggle folders/standard view", FURKMOD_CMD|SDLK_v),
|
||||
D("INS_LIST_MIN", _N("---Instrument list"), NOT_AN_ACTION),
|
||||
D("INS_LIST_ADD", _N("Add instrument"), SDLK_INSERT),
|
||||
D("INS_LIST_DUPLICATE", _N("Duplicate instrument"), FURKMOD_CMD|SDLK_d),
|
||||
D("INS_LIST_OPEN", _N("Open instrument"), 0),
|
||||
D("INS_LIST_OPEN_REPLACE", _N("Open instrument (replace current)"), 0),
|
||||
D("INS_LIST_SAVE", _N("Save instrument"), 0),
|
||||
D("INS_LIST_SAVE_DMP", _N("Save instrument (.dmp)"), 0),
|
||||
D("INS_LIST_MOVE_UP", _N("Move instrument up in list"), FURKMOD_SHIFT|SDLK_UP),
|
||||
D("INS_LIST_MOVE_DOWN", _N("Move instrument down in list"), FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("INS_LIST_DELETE", _N("Delete instrument"), 0),
|
||||
D("INS_LIST_EDIT", _N("Edit instrument"), FURKMOD_SHIFT|SDLK_RETURN),
|
||||
D("INS_LIST_UP", _N("Instrument cursor up"), SDLK_UP),
|
||||
D("INS_LIST_DOWN", _N("Instrument cursor down"), SDLK_DOWN),
|
||||
D("INS_LIST_DIR_VIEW", _N("Instruments: toggle folders/standard view"), FURKMOD_CMD|SDLK_v),
|
||||
D("INS_LIST_SAVE_ALL", _N("Save all instruments"), 0),
|
||||
D("INS_LIST_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("WAVE_LIST_MIN", "---Wavetable list", NOT_AN_ACTION),
|
||||
D("WAVE_LIST_ADD", "Add wavetable", SDLK_INSERT),
|
||||
D("WAVE_LIST_DUPLICATE", "Duplicate wavetable", FURKMOD_CMD|SDLK_d),
|
||||
D("WAVE_LIST_OPEN", "Open wavetable", 0),
|
||||
D("WAVE_LIST_OPEN_REPLACE", "Open wavetable (replace current)", 0),
|
||||
D("WAVE_LIST_SAVE", "Save wavetable", 0),
|
||||
D("WAVE_LIST_SAVE_DMW", "Save wavetable (.dmw)", 0),
|
||||
D("WAVE_LIST_SAVE_RAW", "Save wavetable (raw)", 0),
|
||||
D("WAVE_LIST_MOVE_UP", "Move wavetable up in list", FURKMOD_SHIFT|SDLK_UP),
|
||||
D("WAVE_LIST_MOVE_DOWN", "Move wavetable down in list", FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("WAVE_LIST_DELETE", "Delete wavetable", 0),
|
||||
D("WAVE_LIST_EDIT", "Edit wavetable", FURKMOD_SHIFT|SDLK_RETURN),
|
||||
D("WAVE_LIST_UP", "Wavetable cursor up", SDLK_UP),
|
||||
D("WAVE_LIST_DOWN", "Wavetable cursor down", SDLK_DOWN),
|
||||
D("WAVE_LIST_DIR_VIEW", "Wavetables: toggle folders/standard view", FURKMOD_CMD|SDLK_v),
|
||||
D("WAVE_LIST_MIN", _N("---Wavetable list"), NOT_AN_ACTION),
|
||||
D("WAVE_LIST_ADD", _N("Add wavetable"), SDLK_INSERT),
|
||||
D("WAVE_LIST_DUPLICATE", _N("Duplicate wavetable"), FURKMOD_CMD|SDLK_d),
|
||||
D("WAVE_LIST_OPEN", _N("Open wavetable"), 0),
|
||||
D("WAVE_LIST_OPEN_REPLACE", _N("Open wavetable (replace current)"), 0),
|
||||
D("WAVE_LIST_SAVE", _N("Save wavetable"), 0),
|
||||
D("WAVE_LIST_SAVE_DMW", _N("Save wavetable (.dmw)"), 0),
|
||||
D("WAVE_LIST_SAVE_RAW", _N("Save wavetable (raw)"), 0),
|
||||
D("WAVE_LIST_MOVE_UP", _N("Move wavetable up in list"), FURKMOD_SHIFT|SDLK_UP),
|
||||
D("WAVE_LIST_MOVE_DOWN", _N("Move wavetable down in list"), FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("WAVE_LIST_DELETE", _N("Delete wavetable"), 0),
|
||||
D("WAVE_LIST_EDIT", _N("Edit wavetable"), FURKMOD_SHIFT|SDLK_RETURN),
|
||||
D("WAVE_LIST_UP", _N("Wavetable cursor up"), SDLK_UP),
|
||||
D("WAVE_LIST_DOWN", _N("Wavetable cursor down"), SDLK_DOWN),
|
||||
D("WAVE_LIST_DIR_VIEW", _N("Wavetables: toggle folders/standard view"), FURKMOD_CMD|SDLK_v),
|
||||
D("WAVE_LIST_SAVE_ALL", _N("Save all wavetables"), 0),
|
||||
D("WAVE_LIST_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("SAMPLE_LIST_MIN", "---Sample list", NOT_AN_ACTION),
|
||||
D("SAMPLE_LIST_ADD", "Add sample", SDLK_INSERT),
|
||||
D("SAMPLE_LIST_DUPLICATE", "Duplicate sample", FURKMOD_CMD|SDLK_d),
|
||||
D("SAMPLE_LIST_OPEN", "Open sample", 0),
|
||||
D("SAMPLE_LIST_OPEN_REPLACE", "Open sample (replace current)", 0),
|
||||
D("SAMPLE_LIST_OPEN_RAW", "Import raw sample data", 0),
|
||||
D("SAMPLE_LIST_OPEN_REPLACE_RAW", "Import raw sample data (replace current)", 0),
|
||||
D("SAMPLE_LIST_SAVE", "Save sample", 0),
|
||||
D("SAMPLE_LIST_SAVE_RAW", "Save sample (raw)", 0),
|
||||
D("SAMPLE_LIST_MOVE_UP", "Move sample up in list", FURKMOD_SHIFT|SDLK_UP),
|
||||
D("SAMPLE_LIST_MOVE_DOWN", "Move sample down in list", FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("SAMPLE_LIST_DELETE", "Delete sample", 0),
|
||||
D("SAMPLE_LIST_EDIT", "Edit sample", FURKMOD_SHIFT|SDLK_RETURN),
|
||||
D("SAMPLE_LIST_UP", "Sample cursor up", SDLK_UP),
|
||||
D("SAMPLE_LIST_DOWN", "Sample cursor down", SDLK_DOWN),
|
||||
D("SAMPLE_LIST_PREVIEW", "Sample preview", 0),
|
||||
D("SAMPLE_LIST_STOP_PREVIEW", "Stop sample preview", 0),
|
||||
D("SAMPLE_LIST_DIR_VIEW", "Samples: Toggle folders/standard view", FURKMOD_CMD|SDLK_v),
|
||||
D("SAMPLE_LIST_MAKE_MAP", "Samples: Make me a drum kit", 0),
|
||||
D("SAMPLE_LIST_MIN", _N("---Sample list"), NOT_AN_ACTION),
|
||||
D("SAMPLE_LIST_ADD", _N("Add sample"), SDLK_INSERT),
|
||||
D("SAMPLE_LIST_DUPLICATE", _N("Duplicate sample"), FURKMOD_CMD|SDLK_d),
|
||||
D("SAMPLE_LIST_OPEN", _N("Open sample"), 0),
|
||||
D("SAMPLE_LIST_OPEN_REPLACE", _N("Open sample (replace current)"), 0),
|
||||
D("SAMPLE_LIST_OPEN_RAW", _N("Import raw sample data"), 0),
|
||||
D("SAMPLE_LIST_OPEN_REPLACE_RAW", _N("Import raw sample data (replace current)"), 0),
|
||||
D("SAMPLE_LIST_SAVE", _N("Save sample"), 0),
|
||||
D("SAMPLE_LIST_SAVE_RAW", _N("Save sample (raw)"), 0),
|
||||
D("SAMPLE_LIST_MOVE_UP", _N("Move sample up in list"), FURKMOD_SHIFT|SDLK_UP),
|
||||
D("SAMPLE_LIST_MOVE_DOWN", _N("Move sample down in list"), FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("SAMPLE_LIST_DELETE", _N("Delete sample"), 0),
|
||||
D("SAMPLE_LIST_EDIT", _N("Edit sample"), FURKMOD_SHIFT|SDLK_RETURN),
|
||||
D("SAMPLE_LIST_UP", _N("Sample cursor up"), SDLK_UP),
|
||||
D("SAMPLE_LIST_DOWN", _N("Sample cursor down"), SDLK_DOWN),
|
||||
D("SAMPLE_LIST_PREVIEW", _N("Sample preview"), 0),
|
||||
D("SAMPLE_LIST_STOP_PREVIEW", _N("Stop sample preview"), 0),
|
||||
D("SAMPLE_LIST_DIR_VIEW", _N("Samples: Toggle folders/standard view"), FURKMOD_CMD|SDLK_v),
|
||||
D("SAMPLE_LIST_MAKE_MAP", _N("Samples: Make me a drum kit"), 0),
|
||||
D("SAMPLE_LIST_SAVE_ALL", _N("Save all samples"), 0),
|
||||
D("SAMPLE_LIST_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("SAMPLE_MIN", "---Sample editor", NOT_AN_ACTION),
|
||||
D("SAMPLE_SELECT", "Sample editor mode: Select", FURKMOD_SHIFT|SDLK_i),
|
||||
D("SAMPLE_DRAW", "Sample editor mode: Draw", FURKMOD_SHIFT|SDLK_d),
|
||||
D("SAMPLE_CUT", "Sample editor: Cut", FURKMOD_CMD|SDLK_x),
|
||||
D("SAMPLE_COPY", "Sample editor: Copy", FURKMOD_CMD|SDLK_c),
|
||||
D("SAMPLE_PASTE", "Sample editor: Paste", FURKMOD_CMD|SDLK_v),
|
||||
D("SAMPLE_PASTE_REPLACE", "Sample editor: Paste replace", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_v),
|
||||
D("SAMPLE_PASTE_MIX", "Sample editor: Paste mix", FURKMOD_CMD|FURKMOD_ALT|SDLK_v),
|
||||
D("SAMPLE_SELECT_ALL", "Sample editor: Select all", FURKMOD_CMD|SDLK_a),
|
||||
D("SAMPLE_RESIZE", "Sample editor: Resize", FURKMOD_CMD|SDLK_r),
|
||||
D("SAMPLE_RESAMPLE", "Sample editor: Resample", FURKMOD_CMD|SDLK_e),
|
||||
D("SAMPLE_AMPLIFY", "Sample editor: Amplify", FURKMOD_CMD|SDLK_b),
|
||||
D("SAMPLE_NORMALIZE", "Sample editor: Normalize", FURKMOD_CMD|SDLK_n),
|
||||
D("SAMPLE_FADE_IN", "Sample editor: Fade in", FURKMOD_CMD|SDLK_i),
|
||||
D("SAMPLE_FADE_OUT", "Sample editor: Fade out", FURKMOD_CMD|SDLK_o),
|
||||
D("SAMPLE_SILENCE", "Sample editor: Apply silence", FURKMOD_SHIFT|SDLK_DELETE),
|
||||
D("SAMPLE_INSERT", "Sample editor: Insert silence", SDLK_INSERT),
|
||||
D("SAMPLE_DELETE", "Sample editor: Delete", SDLK_DELETE),
|
||||
D("SAMPLE_TRIM", "Sample editor: Trim", FURKMOD_CMD|SDLK_DELETE),
|
||||
D("SAMPLE_REVERSE", "Sample editor: Reverse", FURKMOD_CMD|SDLK_t),
|
||||
D("SAMPLE_INVERT", "Sample editor: Invert", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_t),
|
||||
D("SAMPLE_SIGN", "Sample editor: Signed/unsigned exchange", FURKMOD_CMD|SDLK_u),
|
||||
D("SAMPLE_FILTER", "Sample editor: Apply filter", FURKMOD_CMD|SDLK_f),
|
||||
D("SAMPLE_CROSSFADE_LOOP", "Sample editor: Crossfade loop points", NOT_AN_ACTION),
|
||||
D("SAMPLE_PREVIEW", "Sample editor: Preview sample", 0),
|
||||
D("SAMPLE_STOP_PREVIEW", "Sample editor: Stop sample preview", 0),
|
||||
D("SAMPLE_ZOOM_IN", "Sample editor: Zoom in", FURKMOD_CMD|SDLK_EQUALS),
|
||||
D("SAMPLE_ZOOM_OUT", "Sample editor: Zoom out", FURKMOD_CMD|SDLK_MINUS),
|
||||
D("SAMPLE_ZOOM_AUTO", "Sample editor: Toggle auto-zoom", FURKMOD_CMD|SDLK_0),
|
||||
D("SAMPLE_MAKE_INS", "Sample editor: Create instrument from sample", 0),
|
||||
D("SAMPLE_SET_LOOP", "Sample editor: Set loop to selection", FURKMOD_CMD|SDLK_l),
|
||||
D("SAMPLE_CREATE_WAVE", "Sample editor: Create wavetable from selection", FURKMOD_CMD|SDLK_w),
|
||||
D("SAMPLE_MIN", _N("---Sample editor"), NOT_AN_ACTION),
|
||||
D("SAMPLE_SELECT", _N("Sample editor mode: Select"), FURKMOD_SHIFT|SDLK_i),
|
||||
D("SAMPLE_DRAW", _N("Sample editor mode: Draw"), FURKMOD_SHIFT|SDLK_d),
|
||||
D("SAMPLE_CUT", _N("Sample editor: Cut"), FURKMOD_CMD|SDLK_x),
|
||||
D("SAMPLE_COPY", _N("Sample editor: Copy"), FURKMOD_CMD|SDLK_c),
|
||||
D("SAMPLE_PASTE", _N("Sample editor: Paste"), FURKMOD_CMD|SDLK_v),
|
||||
D("SAMPLE_PASTE_REPLACE", _N("Sample editor: Paste replace"), FURKMOD_CMD|FURKMOD_SHIFT|SDLK_v),
|
||||
D("SAMPLE_PASTE_MIX", _N("Sample editor: Paste mix"), FURKMOD_CMD|FURKMOD_ALT|SDLK_v),
|
||||
D("SAMPLE_SELECT_ALL", _N("Sample editor: Select all"), FURKMOD_CMD|SDLK_a),
|
||||
D("SAMPLE_RESIZE", _N("Sample editor: Resize"), FURKMOD_CMD|SDLK_r),
|
||||
D("SAMPLE_RESAMPLE", _N("Sample editor: Resample"), FURKMOD_CMD|SDLK_e),
|
||||
D("SAMPLE_AMPLIFY", _N("Sample editor: Amplify"), FURKMOD_CMD|SDLK_b),
|
||||
D("SAMPLE_NORMALIZE", _N("Sample editor: Normalize"), FURKMOD_CMD|SDLK_n),
|
||||
D("SAMPLE_FADE_IN", _N("Sample editor: Fade in"), FURKMOD_CMD|SDLK_i),
|
||||
D("SAMPLE_FADE_OUT", _N("Sample editor: Fade out"), FURKMOD_CMD|SDLK_o),
|
||||
D("SAMPLE_SILENCE", _N("Sample editor: Apply silence"), FURKMOD_SHIFT|SDLK_DELETE),
|
||||
D("SAMPLE_INSERT", _N("Sample editor: Insert silence"), SDLK_INSERT),
|
||||
D("SAMPLE_DELETE", _N("Sample editor: Delete"), SDLK_DELETE),
|
||||
D("SAMPLE_TRIM", _N("Sample editor: Trim"), FURKMOD_CMD|SDLK_DELETE),
|
||||
D("SAMPLE_REVERSE", _N("Sample editor: Reverse"), FURKMOD_CMD|SDLK_t),
|
||||
D("SAMPLE_INVERT", _N("Sample editor: Invert"), FURKMOD_CMD|FURKMOD_SHIFT|SDLK_t),
|
||||
D("SAMPLE_SIGN", _N("Sample editor: Signed/unsigned exchange"), FURKMOD_CMD|SDLK_u),
|
||||
D("SAMPLE_FILTER", _N("Sample editor: Apply filter"), FURKMOD_CMD|SDLK_f),
|
||||
D("SAMPLE_CROSSFADE_LOOP", _N("Sample editor: Crossfade loop points"), NOT_AN_ACTION),
|
||||
D("SAMPLE_PREVIEW", _N("Sample editor: Preview sample"), 0),
|
||||
D("SAMPLE_STOP_PREVIEW", _N("Sample editor: Stop sample preview"), 0),
|
||||
D("SAMPLE_ZOOM_IN", _N("Sample editor: Zoom in"), FURKMOD_CMD|SDLK_EQUALS),
|
||||
D("SAMPLE_ZOOM_OUT", _N("Sample editor: Zoom out"), FURKMOD_CMD|SDLK_MINUS),
|
||||
D("SAMPLE_ZOOM_AUTO", _N("Sample editor: Toggle auto-zoom"), FURKMOD_CMD|SDLK_0),
|
||||
D("SAMPLE_MAKE_INS", _N("Sample editor: Create instrument from sample"), 0),
|
||||
D("SAMPLE_SET_LOOP", _N("Sample editor: Set loop to selection"), FURKMOD_CMD|SDLK_l),
|
||||
D("SAMPLE_CREATE_WAVE", _N("Sample editor: Create wavetable from selection"), FURKMOD_CMD|SDLK_w),
|
||||
D("SAMPLE_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("ORDERS_MIN", "---Orders", NOT_AN_ACTION),
|
||||
D("ORDERS_UP", "Previous order", SDLK_UP),
|
||||
D("ORDERS_DOWN", "Next order", SDLK_DOWN),
|
||||
D("ORDERS_LEFT", "Order cursor left", SDLK_LEFT),
|
||||
D("ORDERS_RIGHT", "Order cursor right", SDLK_RIGHT),
|
||||
D("ORDERS_INCREASE", "Increase order value", 0),
|
||||
D("ORDERS_DECREASE", "Decrease order value", 0),
|
||||
D("ORDERS_EDIT_MODE", "Switch order edit mode", 0),
|
||||
D("ORDERS_LINK", "Order: toggle alter entire row", FURKMOD_CMD|SDLK_l),
|
||||
D("ORDERS_ADD", "Add order", SDLK_INSERT),
|
||||
D("ORDERS_DUPLICATE", "Duplicate order", FURKMOD_CMD|SDLK_d),
|
||||
D("ORDERS_DEEP_CLONE", "Deep clone order", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_d),
|
||||
D("ORDERS_DUPLICATE_END", "Copy current order to end of song", FURKMOD_CMD|SDLK_e),
|
||||
D("ORDERS_DEEP_CLONE_END", "Deep clone current order to end of song", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_e),
|
||||
D("ORDERS_REMOVE", "Remove order", SDLK_DELETE),
|
||||
D("ORDERS_MOVE_UP", "Move order up", FURKMOD_SHIFT|SDLK_UP),
|
||||
D("ORDERS_MOVE_DOWN", "Move order down", FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("ORDERS_REPLAY", "Replay order", 0),
|
||||
D("ORDERS_MIN", _N("---Orders"), NOT_AN_ACTION),
|
||||
D("ORDERS_UP", _N("Previous order"), SDLK_UP),
|
||||
D("ORDERS_DOWN", _N("Next order"), SDLK_DOWN),
|
||||
D("ORDERS_LEFT", _N("Order cursor left"), SDLK_LEFT),
|
||||
D("ORDERS_RIGHT", _N("Order cursor right"), SDLK_RIGHT),
|
||||
D("ORDERS_INCREASE", _N("Increase order value"), 0),
|
||||
D("ORDERS_DECREASE", _N("Decrease order value"), 0),
|
||||
D("ORDERS_EDIT_MODE", _N("Switch order edit mode"), 0),
|
||||
D("ORDERS_LINK", _N("Order: toggle alter entire row"), FURKMOD_CMD|SDLK_l),
|
||||
D("ORDERS_ADD", _N("Add order"), SDLK_INSERT),
|
||||
D("ORDERS_DUPLICATE", _N("Duplicate order"), FURKMOD_CMD|SDLK_d),
|
||||
D("ORDERS_DEEP_CLONE", _N("Deep clone order"), FURKMOD_CMD|FURKMOD_SHIFT|SDLK_d),
|
||||
D("ORDERS_DUPLICATE_END", _N("Copy current order to end of song"), FURKMOD_CMD|SDLK_e),
|
||||
D("ORDERS_DEEP_CLONE_END", _N("Deep clone current order to end of song"), FURKMOD_CMD|FURKMOD_SHIFT|SDLK_e),
|
||||
D("ORDERS_REMOVE", _N("Remove order"), SDLK_DELETE),
|
||||
D("ORDERS_MOVE_UP", _N("Move order up"), FURKMOD_SHIFT|SDLK_UP),
|
||||
D("ORDERS_MOVE_DOWN", _N("Move order down"), FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("ORDERS_REPLAY", _N("Replay order"), 0),
|
||||
D("ORDERS_MAX", "", NOT_AN_ACTION),
|
||||
};
|
||||
#undef D
|
||||
|
|
@ -952,10 +963,15 @@ const FurnaceGUIColorDef guiColors[GUI_COLOR_MAX]={
|
|||
D(GUI_COLOR_FM_SSG,"",ImVec4(1.0f,1.0f,1.0f,1.0f)),
|
||||
D(GUI_COLOR_FM_WAVE,"",ImVec4(1.0f,1.0f,1.0f,1.0f)),
|
||||
|
||||
D(GUI_COLOR_MACRO_HIGHLIGHT,"",ImVec4(1.0f,1.0f,1.0f,1.0f)),
|
||||
D(GUI_COLOR_MACRO_VOLUME,"",ImVec4(0.2f,1.0f,0.0f,1.0f)),
|
||||
D(GUI_COLOR_MACRO_PITCH,"",ImVec4(1.0f,0.8f,0.0f,1.0f)),
|
||||
D(GUI_COLOR_MACRO_OTHER,"",ImVec4(0.0f,0.9f,1.0f,1.0f)),
|
||||
D(GUI_COLOR_MACRO_WAVE,"",ImVec4(1.0f,0.4f,0.0f,1.0f)),
|
||||
D(GUI_COLOR_MACRO_NOISE,"",ImVec4(0.8f,0.8f,0.8f,1.0f)),
|
||||
D(GUI_COLOR_MACRO_FILTER,"",ImVec4(0.4f,0.2f,1.0f,1.0f)),
|
||||
D(GUI_COLOR_MACRO_ENVELOPE,"",ImVec4(0.0f,1.0f,0.5f,1.0f)),
|
||||
D(GUI_COLOR_MACRO_GLOBAL,"",ImVec4(1.0f,0.1f,0.1f,1.0f)),
|
||||
|
||||
D(GUI_COLOR_INSTR_STD,"",ImVec4(0.6f,1.0f,0.5f,1.0f)),
|
||||
D(GUI_COLOR_INSTR_FM,"",ImVec4(0.6f,0.9f,1.0f,1.0f)),
|
||||
|
|
@ -1019,6 +1035,8 @@ const FurnaceGUIColorDef guiColors[GUI_COLOR_MAX]={
|
|||
D(GUI_COLOR_INSTR_NDS,"",ImVec4(0.7f,0.7f,0.8f,1.0f)),
|
||||
D(GUI_COLOR_INSTR_GBA_DMA,"",ImVec4(0.6f,0.4f,1.0f,1.0f)),
|
||||
D(GUI_COLOR_INSTR_GBA_MINMOD,"",ImVec4(0.5f,0.45f,0.7f,1.0f)),
|
||||
D(GUI_COLOR_INSTR_BIFURCATOR,"",ImVec4(0.8925f,0.8925f,0.8925f,1.0f)),
|
||||
D(GUI_COLOR_INSTR_SID2,"",ImVec4(0.6f,0.75f,1.0f,1.0f)),
|
||||
D(GUI_COLOR_INSTR_UNKNOWN,"",ImVec4(0.3f,0.3f,0.3f,1.0f)),
|
||||
|
||||
D(GUI_COLOR_CHANNEL_BG,"",ImVec4(0.4f,0.6f,0.8f,1.0f)),
|
||||
|
|
@ -1265,6 +1283,8 @@ const int availableSystems[]={
|
|||
DIV_SYSTEM_DAVE,
|
||||
DIV_SYSTEM_NDS,
|
||||
DIV_SYSTEM_5E01,
|
||||
DIV_SYSTEM_BIFURCATOR,
|
||||
DIV_SYSTEM_SID2,
|
||||
0 // don't remove this last one!
|
||||
};
|
||||
|
||||
|
|
@ -1358,6 +1378,8 @@ const int chipsSpecial[]={
|
|||
DIV_SYSTEM_DAVE,
|
||||
DIV_SYSTEM_NDS,
|
||||
DIV_SYSTEM_5E01,
|
||||
DIV_SYSTEM_BIFURCATOR,
|
||||
DIV_SYSTEM_SID2,
|
||||
0 // don't remove this last one!
|
||||
};
|
||||
|
||||
|
|
@ -1397,11 +1419,11 @@ const int* chipCategories[]={
|
|||
};
|
||||
|
||||
const char* chipCategoryNames[]={
|
||||
"All chips",
|
||||
"FM",
|
||||
"Square",
|
||||
"Wavetable",
|
||||
"Special",
|
||||
"Sample",
|
||||
_N("All chips"),
|
||||
_N("FM"),
|
||||
_N("Square"),
|
||||
_N("Wavetable"),
|
||||
_N("Special"),
|
||||
_N("Sample"),
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
|
|
@ -53,8 +53,20 @@ FurnaceGUITexture* FurnaceGUI::getTexture(FurnaceGUIImages image, FurnaceGUIBlen
|
|||
if (img->data==NULL) return NULL;
|
||||
if (img->width<=0 || img->height<=0) return NULL;
|
||||
|
||||
bool createTex=false;
|
||||
|
||||
if (img->tex==NULL) {
|
||||
img->tex=rend->createTexture(false,img->width,img->height);
|
||||
createTex=true;
|
||||
} else {
|
||||
if (!rend->isTextureValid(img->tex)) {
|
||||
rend->destroyTexture(img->tex);
|
||||
img->tex=NULL;
|
||||
createTex=true;
|
||||
}
|
||||
}
|
||||
|
||||
if (createTex) {
|
||||
img->tex=rend->createTexture(false,img->width,img->height,true,bestTexFormat);
|
||||
if (img->tex==NULL) {
|
||||
logE("error while creating image %d texture! %s",(int)image,SDL_GetError());
|
||||
return NULL;
|
||||
|
|
@ -101,6 +113,44 @@ FurnaceGUIImage* FurnaceGUI::getImage(FurnaceGUIImages image) {
|
|||
}
|
||||
#endif
|
||||
|
||||
if (ret->ch==4) {
|
||||
size_t total=ret->width*ret->height*ret->ch;
|
||||
switch (bestTexFormat) {
|
||||
case GUI_TEXFORMAT_ARGB32:
|
||||
for (size_t i=0; i<total; i+=4) {
|
||||
ret->data[i]^=ret->data[i|2];
|
||||
ret->data[i|2]^=ret->data[i];
|
||||
ret->data[i]^=ret->data[i|2];
|
||||
}
|
||||
break;
|
||||
case GUI_TEXFORMAT_BGRA32:
|
||||
for (size_t i=0; i<total; i+=4) {
|
||||
ret->data[i]^=ret->data[i|3];
|
||||
ret->data[i|3]^=ret->data[i];
|
||||
ret->data[i]^=ret->data[i|3];
|
||||
ret->data[i|1]^=ret->data[i|2];
|
||||
ret->data[i|2]^=ret->data[i|1];
|
||||
ret->data[i|1]^=ret->data[i|2];
|
||||
ret->data[i|1]^=ret->data[i|3];
|
||||
ret->data[i|3]^=ret->data[i|1];
|
||||
ret->data[i|1]^=ret->data[i|3];
|
||||
}
|
||||
break;
|
||||
case GUI_TEXFORMAT_RGBA32:
|
||||
for (size_t i=0; i<total; i+=4) {
|
||||
ret->data[i]^=ret->data[i|3];
|
||||
ret->data[i|3]^=ret->data[i];
|
||||
ret->data[i]^=ret->data[i|3];
|
||||
ret->data[i|1]^=ret->data[i|2];
|
||||
ret->data[i|2]^=ret->data[i|1];
|
||||
ret->data[i|1]^=ret->data[i|2];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
images[image]=ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
6597
src/gui/insEdit.cpp
6597
src/gui/insEdit.cpp
File diff suppressed because it is too large
Load diff
|
|
@ -27,6 +27,8 @@ void FurnaceGUI::drawImage(ImDrawList* dl, FurnaceGUIImages image, const ImVec2&
|
|||
FurnaceGUIImage* imgI=getImage(image);
|
||||
FurnaceGUITexture* img=getTexture(image);
|
||||
|
||||
if (img==NULL) return;
|
||||
|
||||
float squareSize=MAX(introMax.x-introMin.x,introMax.y-introMin.y);
|
||||
float uDiff=uvMax.x-uvMin.x;
|
||||
float vDiff=uvMax.y-uvMin.y;
|
||||
|
|
@ -63,10 +65,13 @@ void FurnaceGUI::drawImage(ImDrawList* dl, FurnaceGUIImages image, const ImVec2&
|
|||
posAbs.y+rectMin.x*sin(rotate)+rectMax.y*cos(rotate)
|
||||
);
|
||||
|
||||
ImVec2 uv0=ImVec2(uvMin.x,uvMin.y);
|
||||
ImVec2 uv1=ImVec2(uvMax.x,uvMin.y);
|
||||
ImVec2 uv2=ImVec2(uvMax.x,uvMax.y);
|
||||
ImVec2 uv3=ImVec2(uvMin.x,uvMax.y);
|
||||
float uScale=rend->getTextureU(img);
|
||||
float vScale=rend->getTextureV(img);
|
||||
|
||||
ImVec2 uv0=ImVec2(uvMin.x*uScale,uvMin.y*vScale);
|
||||
ImVec2 uv1=ImVec2(uvMax.x*uScale,uvMin.y*vScale);
|
||||
ImVec2 uv2=ImVec2(uvMax.x*uScale,uvMax.y*vScale);
|
||||
ImVec2 uv3=ImVec2(uvMin.x*uScale,uvMax.y*vScale);
|
||||
|
||||
ImU32 colorConverted=ImGui::GetColorU32(imgColor);
|
||||
|
||||
|
|
@ -81,7 +86,7 @@ void FurnaceGUI::endIntroTune() {
|
|||
e->createNewFromDefaults();
|
||||
} else { // load pending song
|
||||
if (load(curFileName)>0) {
|
||||
showError(fmt::sprintf("Error while loading file! (%s)",lastError));
|
||||
showError(fmt::sprintf(_("Error while loading file! (%s)"),lastError));
|
||||
curFileName="";
|
||||
e->createNewFromDefaults();
|
||||
}
|
||||
|
|
@ -114,9 +119,9 @@ void FurnaceGUI::drawIntro(double introTime, bool monitor) {
|
|||
ImGui::SetNextWindowSize(ImVec2(canvasW,canvasH));
|
||||
if (introPos<0.1) ImGui::SetNextWindowFocus();
|
||||
}
|
||||
if (ImGui::Begin(monitor?"IntroMon X":"Intro",NULL,monitor?globalWinFlags:(ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoDocking|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoBackground))) {
|
||||
if (ImGui::Begin(monitor?"IntroMon X":"Intro",NULL,monitor?globalWinFlags:(ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoDocking|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoBackground),monitor?_("IntroMon X"):_("Intro"))) {
|
||||
if (monitor) {
|
||||
if (ImGui::Button("Preview")) {
|
||||
if (ImGui::Button(_("Preview"))) {
|
||||
introPos=0;
|
||||
tutorial.introPlayed=false;
|
||||
shortIntro=false;
|
||||
|
|
@ -168,9 +173,9 @@ void FurnaceGUI::drawIntro(double introTime, bool monitor) {
|
|||
|
||||
if (monitor) {
|
||||
ImVec2 textPos=ImLerp(top,bottom,ImVec2(0.5,0.5));
|
||||
textPos.x-=ImGui::CalcTextSize("SORRY NOTHING").x*0.5;
|
||||
textPos.y-=ImGui::CalcTextSize("SORRY NOTHING").y*0.5;
|
||||
dl->AddText(textPos,ImGui::GetColorU32(uiColors[GUI_COLOR_TEXT]),"SORRY NOTHING");
|
||||
textPos.x-=ImGui::CalcTextSize(_("SORRY NOTHING")).x*0.5;
|
||||
textPos.y-=ImGui::CalcTextSize(_("SORRY NOTHING")).y*0.5;
|
||||
dl->AddText(textPos,ImGui::GetColorU32(uiColors[GUI_COLOR_TEXT]),_("SORRY NOTHING"));
|
||||
}
|
||||
|
||||
if (introSkip<0.5 || monitor) {
|
||||
|
|
@ -302,7 +307,7 @@ void FurnaceGUI::drawIntro(double introTime, bool monitor) {
|
|||
}
|
||||
|
||||
dl->AddRectFilled(top,bottom,ImGui::GetColorU32(ImVec4(0.0,0.0,0.0,CLAMP(introSkip*2.0,0.0,1.0)-CLAMP((introSkip-0.5)*4,0.0,1.0))));
|
||||
if (introSkip<0.5) dl->AddText(ImVec2(8.0*dpiScale,8.0*dpiScale),ImGui::GetColorU32(ImVec4(1.0,1.0,1.0,CLAMP(introSkip*8.0,0.0,1.0))),"hold to skip");
|
||||
if (introSkip<0.5) dl->AddText(ImVec2(8.0*dpiScale,8.0*dpiScale),ImGui::GetColorU32(ImVec4(1.0,1.0,1.0,CLAMP(introSkip*8.0,0.0,1.0))),_("hold to skip"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
19799
src/gui/introTune.cpp
19799
src/gui/introTune.cpp
File diff suppressed because it is too large
Load diff
|
|
@ -22,11 +22,11 @@
|
|||
#include <imgui.h>
|
||||
|
||||
const char* logLevels[5]={
|
||||
"ERROR",
|
||||
"warning",
|
||||
"info",
|
||||
"debug",
|
||||
"trace"
|
||||
_N("ERROR"),
|
||||
_N("warning"),
|
||||
_N("info"),
|
||||
_N("debug"),
|
||||
_N("trace")
|
||||
};
|
||||
|
||||
FurnaceGUIColors logColors[5]={
|
||||
|
|
@ -44,13 +44,13 @@ void FurnaceGUI::drawLog() {
|
|||
nextWindow=GUI_WINDOW_NOTHING;
|
||||
}
|
||||
if (!logOpen) return;
|
||||
if (ImGui::Begin("Log Viewer",&logOpen,globalWinFlags)) {
|
||||
ImGui::Checkbox("Follow",&followLog);
|
||||
if (ImGui::Begin("Log Viewer",&logOpen,globalWinFlags,_("Log Viewer"))) {
|
||||
ImGui::Checkbox(_("Follow"),&followLog);
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("Level");
|
||||
ImGui::Text(_("Level"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::Combo("##LogLevel",&logLevel,logLevels,5);
|
||||
ImGui::Combo("##LogLevel",&logLevel,LocalizedComboGetter,logLevels,5);
|
||||
if (ImGui::BeginTable("LogView",3,ImGuiTableFlags_ScrollY|ImGuiTableFlags_BordersInnerV)) {
|
||||
ImGui::PushFont(patFont);
|
||||
|
||||
|
|
@ -65,11 +65,11 @@ void FurnaceGUI::drawLog() {
|
|||
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted("time");
|
||||
ImGui::TextUnformatted(_("time"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted("level");
|
||||
ImGui::TextUnformatted(_("level"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted("message");
|
||||
ImGui::TextUnformatted(_("message"));
|
||||
|
||||
int pos=logPosition;
|
||||
for (int i=0; i<TA_LOG_SIZE; i++) {
|
||||
|
|
@ -80,7 +80,7 @@ void FurnaceGUI::drawLog() {
|
|||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%02d:%02d:%02d",logEntry.time.tm_hour,logEntry.time.tm_min,logEntry.time.tm_sec);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(uiColors[logColors[logEntry.loglevel]],"%s",logLevels[logEntry.loglevel]);
|
||||
ImGui::TextColored(uiColors[logColors[logEntry.loglevel]],"%s",_(logLevels[logEntry.loglevel]));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextWrapped("%s",logEntry.text.c_str());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ void FurnaceGUI::drawMemory() {
|
|||
nextWindow=GUI_WINDOW_NOTHING;
|
||||
}
|
||||
if (!memoryOpen) return;
|
||||
if (ImGui::Begin("Memory Composition",&memoryOpen,globalWinFlags)) {
|
||||
if (ImGui::Begin("Memory Composition",&memoryOpen,globalWinFlags,_("Memory Composition"))) {
|
||||
ImDrawList* dl=ImGui::GetWindowDrawList();
|
||||
ImGuiWindow* window=ImGui::GetCurrentWindow();
|
||||
char tempID[1024];
|
||||
|
|
@ -47,7 +47,11 @@ void FurnaceGUI::drawMemory() {
|
|||
|
||||
ImGui::Text("%s: %s",e->getSystemName(e->song.system[i]),mc->name.c_str());
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%d/%d (%.1f%%)",(int)mc->used,(int)mc->capacity,100.0*(double)mc->used/(double)mc->capacity);
|
||||
if (mc->capacity>=1024 && settings.memUsageUnit==1) {
|
||||
ImGui::Text("%dK/%dK (%.1f%%)",(int)mc->used>>10,(int)mc->capacity>>10,100.0*(double)mc->used/(double)mc->capacity);
|
||||
} else {
|
||||
ImGui::Text("%d/%d (%.1f%%)",(int)mc->used,(int)mc->capacity,100.0*(double)mc->used/(double)mc->capacity);
|
||||
}
|
||||
|
||||
ImVec2 size=ImVec2(ImGui::GetContentRegionAvail().x,36.0f*dpiScale);
|
||||
ImVec2 minArea=window->DC.CursorPos;
|
||||
|
|
@ -139,15 +143,22 @@ void FurnaceGUI::drawMemory() {
|
|||
DivSample* sample=e->getSample(entry.asset);
|
||||
ImGui::Text("%d: %s",curHover,sample->name.c_str());
|
||||
if ((int)entry.type>=(int)DIV_MEMORY_BANK0) {
|
||||
ImGui::Text("bank %d",(int)entry.type-(int)DIV_MEMORY_BANK0);
|
||||
ImGui::Text(_("bank %d"),(int)entry.type-(int)DIV_MEMORY_BANK0);
|
||||
}
|
||||
if ((entry.end-entry.begin)>=1024 && settings.memUsageUnit==1) {
|
||||
ImGui::Text("%d-%d ($%x-$%x): %dK ($%x)",(int)entry.begin,(int)entry.end-1,(int)entry.begin,(int)entry.end-1,(int)(entry.end-entry.begin)>>10,(int)(entry.end-entry.begin));
|
||||
} else {
|
||||
ImGui::Text("%d-%d ($%x-$%x): %d bytes ($%x)",(int)entry.begin,(int)entry.end-1,(int)entry.begin,(int)entry.end-1,(int)(entry.end-entry.begin),(int)(entry.end-entry.begin));
|
||||
}
|
||||
ImGui::Text("%d-%d ($%x-$%x): %d bytes ($%x)",(int)entry.begin,(int)entry.end-1,(int)entry.begin,(int)entry.end-1,(int)(entry.end-entry.begin),(int)(entry.end-entry.begin));
|
||||
ImGui::Text("click to open sample editor");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ImGui::Text("%d: %s",curHover,entry.name.c_str());
|
||||
ImGui::Text("%d-%d ($%x-$%x): %d bytes ($%x)",(int)entry.begin,(int)entry.end-1,(int)entry.begin,(int)entry.end-1,(int)(entry.end-entry.begin),(int)(entry.end-entry.begin));
|
||||
if ((entry.end-entry.begin)>=1024 && settings.memUsageUnit==1) {
|
||||
ImGui::Text("%d-%d ($%x-$%x): %dK ($%x)",(int)entry.begin,(int)entry.end-1,(int)entry.begin,(int)entry.end-1,(int)(entry.end-entry.begin)>>10,(int)(entry.end-entry.begin));
|
||||
} else {
|
||||
ImGui::Text("%d-%d ($%x-$%x): %d bytes ($%x)",(int)entry.begin,(int)entry.end-1,(int)entry.begin,(int)entry.end-1,(int)(entry.end-entry.begin),(int)(entry.end-entry.begin));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -161,8 +172,8 @@ void FurnaceGUI::drawMemory() {
|
|||
|
||||
if (!have) {
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY()+(ImGui::GetContentRegionAvail().y-ImGui::GetFrameHeight()+ImGui::GetStyle().ItemSpacing.y)*0.5f);
|
||||
CENTER_TEXT("no chips with memory");
|
||||
ImGui::Text("no chips with memory");
|
||||
CENTER_TEXT(_("no chips with memory"));
|
||||
ImGui::Text(_("no chips with memory"));
|
||||
}
|
||||
}
|
||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_MEMORY;
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@
|
|||
#include "imgui_internal.h"
|
||||
|
||||
const char* portNamesStereo[2]={
|
||||
"left",
|
||||
"right"
|
||||
_N("left"),
|
||||
_N("right")
|
||||
};
|
||||
|
||||
ImVec2 FurnaceGUI::calcPortSetSize(String label, int ins, int outs) {
|
||||
|
|
@ -125,10 +125,10 @@ bool FurnaceGUI::portSet(String label, unsigned int portSetID, int ins, int outs
|
|||
|
||||
// input ports
|
||||
for (int i=0; i<ins; i++) {
|
||||
String portLabel="input";
|
||||
String portLabel=_("input");
|
||||
String subPortID=fmt::sprintf("subPort%.5x",(portSetID<<4)|i);
|
||||
if (ins==2) {
|
||||
portLabel=portNamesStereo[i&1];
|
||||
portLabel=_(portNamesStereo[i&1]);
|
||||
} else if (ins>2) {
|
||||
portLabel=fmt::sprintf("%d",i+1);
|
||||
}
|
||||
|
|
@ -165,10 +165,10 @@ bool FurnaceGUI::portSet(String label, unsigned int portSetID, int ins, int outs
|
|||
|
||||
// output ports
|
||||
for (int i=0; i<outs; i++) {
|
||||
String portLabel="output";
|
||||
String portLabel=_("output");
|
||||
String subPortID=fmt::sprintf("subPort%.5x",(portSetID<<4)|i);
|
||||
if (outs==2) {
|
||||
portLabel=portNamesStereo[i&1];
|
||||
portLabel=_(portNamesStereo[i&1]);
|
||||
} else if (outs>2) {
|
||||
portLabel=fmt::sprintf("%d",i+1);
|
||||
}
|
||||
|
|
@ -223,10 +223,10 @@ void FurnaceGUI::drawMixer() {
|
|||
} else {
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(400.0f*dpiScale,200.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||
}
|
||||
if (ImGui::Begin("Mixer",&mixerOpen,globalWinFlags|(settings.allowEditDocking?0:ImGuiWindowFlags_NoDocking))) {
|
||||
if (ImGui::Begin("Mixer",&mixerOpen,globalWinFlags|(settings.allowEditDocking?0:ImGuiWindowFlags_NoDocking),_("Mixer"))) {
|
||||
if (ImGui::BeginTabBar("MixerView")) {
|
||||
if (ImGui::BeginTabItem("Mixer")) {
|
||||
if (ImGui::SliderFloat("Master Volume",&e->song.masterVol,0,3,"%.2fx")) {
|
||||
if (ImGui::BeginTabItem(_("Mixer"))) {
|
||||
if (ImGui::SliderFloat(_("Master Volume"),&e->song.masterVol,0,3,"%.2fx")) {
|
||||
if (e->song.masterVol<0) e->song.masterVol=0;
|
||||
if (e->song.masterVol>3) e->song.masterVol=3;
|
||||
MARK_MODIFIED;
|
||||
|
|
@ -247,7 +247,7 @@ void FurnaceGUI::drawMixer() {
|
|||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("%d. %s",i+1,getSystemName(e->song.system[i]));
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Checkbox("Invert",&doInvert)) {
|
||||
if (ImGui::Checkbox(_("Invert"),&doInvert)) {
|
||||
e->song.systemVol[i]=-e->song.systemVol[i];
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
|
|
@ -265,7 +265,7 @@ void FurnaceGUI::drawMixer() {
|
|||
MARK_MODIFIED;
|
||||
} rightClickable
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Volume");
|
||||
ImGui::Text(_("Volume"));
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
|
@ -276,7 +276,7 @@ void FurnaceGUI::drawMixer() {
|
|||
MARK_MODIFIED;
|
||||
} rightClickable
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Panning");
|
||||
ImGui::Text(_("Panning"));
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
|
@ -287,7 +287,7 @@ void FurnaceGUI::drawMixer() {
|
|||
MARK_MODIFIED;
|
||||
} rightClickable
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Front/Rear");
|
||||
ImGui::Text(_("Front/Rear"));
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
|
@ -296,20 +296,20 @@ void FurnaceGUI::drawMixer() {
|
|||
}
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Patchbay")) {
|
||||
if (ImGui::BeginTabItem(_("Patchbay"))) {
|
||||
std::map<unsigned int,ImVec2> portPos;
|
||||
|
||||
if (ImGui::BeginTable("PatchbayOptions",3)) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Checkbox("Automatic patchbay",&e->song.patchbayAuto)) {
|
||||
if (ImGui::Checkbox(_("Automatic patchbay"),&e->song.patchbayAuto)) {
|
||||
if (e->song.patchbayAuto) e->autoPatchbayP();
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox("Display hidden ports",&displayHiddenPorts);
|
||||
ImGui::Checkbox(_("Display hidden ports"),&displayHiddenPorts);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox("Display internal",&displayInternalPorts);
|
||||
ImGui::Checkbox(_("Display internal"),&displayInternalPorts);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
|
|
@ -319,7 +319,7 @@ void FurnaceGUI::drawMixer() {
|
|||
if (ImGui::BeginChild("Patchbay",ImVec2(0,0),true)) {
|
||||
ImDrawList* dl=ImGui::GetWindowDrawList();
|
||||
ImVec2 topPos=ImGui::GetCursorPos();
|
||||
ImVec2 sysSize=calcPortSetSize("System",displayHiddenPorts?DIV_MAX_OUTPUTS:e->getAudioDescGot().outChans,0);
|
||||
ImVec2 sysSize=calcPortSetSize(_("System"),displayHiddenPorts?DIV_MAX_OUTPUTS:e->getAudioDescGot().outChans,0);
|
||||
topPos.x+=ImGui::GetContentRegionAvail().x-sysSize.x;
|
||||
if (ImGui::GetContentRegionAvail().y>sysSize.y) topPos.y+=(ImGui::GetContentRegionAvail().y-sysSize.y)*0.5+ImGui::GetScrollY();
|
||||
|
||||
|
|
@ -351,7 +351,7 @@ void FurnaceGUI::drawMixer() {
|
|||
|
||||
// metronome/sample preview
|
||||
if (displayInternalPorts) {
|
||||
if (portSet("Sample Preview",0xffd,0,1,0,1,selectedSubPort,portPos)) {
|
||||
if (portSet(_("Sample Preview"),0xffd,0,1,0,1,selectedSubPort,portPos)) {
|
||||
selectedPortSet=0xffd;
|
||||
if (selectedSubPort>=0) {
|
||||
portDragActive=true;
|
||||
|
|
@ -364,7 +364,7 @@ void FurnaceGUI::drawMixer() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (portSet("Metronome",0xffe,0,1,0,1,selectedSubPort,portPos)) {
|
||||
if (portSet(_("Metronome"),0xffe,0,1,0,1,selectedSubPort,portPos)) {
|
||||
selectedPortSet=0xffe;
|
||||
if (selectedSubPort>=0) {
|
||||
portDragActive=true;
|
||||
|
|
@ -380,7 +380,7 @@ void FurnaceGUI::drawMixer() {
|
|||
}
|
||||
|
||||
ImGui::SetCursorPos(topPos);
|
||||
if (portSet("System",0x1000,displayHiddenPorts?DIV_MAX_OUTPUTS:e->getAudioDescGot().outChans,0,e->getAudioDescGot().outChans,0,selectedSubPort,portPos)) {
|
||||
if (portSet(_("System"),0x1000,displayHiddenPorts?DIV_MAX_OUTPUTS:e->getAudioDescGot().outChans,0,e->getAudioDescGot().outChans,0,selectedSubPort,portPos)) {
|
||||
selectedPortSet=0x1000;
|
||||
if (selectedSubPort>=0) {
|
||||
portDragActive=true;
|
||||
|
|
@ -443,7 +443,7 @@ void FurnaceGUI::drawMixer() {
|
|||
}
|
||||
}
|
||||
if (ImGui::BeginPopup("SubPortOptions",ImGuiWindowFlags_NoMove|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings)) {
|
||||
if (ImGui::MenuItem("disconnect all")) {
|
||||
if (ImGui::MenuItem(_("disconnect all"))) {
|
||||
e->patchDisconnectAll(selectedPortSet);
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
String sysDefID;
|
||||
|
||||
void FurnaceGUI::drawSysDefs(std::vector<FurnaceGUISysDef>& category, bool& accepted, std::vector<int>& sysDefStack) {
|
||||
void FurnaceGUI::drawSysDefs(std::vector<FurnaceGUISysDef>& category, bool& accepted, std::vector<int>& sysDefStack, bool& alreadyHover) {
|
||||
int index=0;
|
||||
String sysDefIDLeader="##NS";
|
||||
for (int i: sysDefStack) {
|
||||
|
|
@ -53,16 +53,17 @@ void FurnaceGUI::drawSysDefs(std::vector<FurnaceGUISysDef>& category, bool& acce
|
|||
}
|
||||
if (ImGui::IsItemHovered()) isHovered=true;
|
||||
} else if (i.subDefs.empty()) {
|
||||
ImGui::TextUnformatted(i.name);
|
||||
ImGui::TextUnformatted(i.name.c_str());
|
||||
if (ImGui::IsItemHovered()) isHovered=true;
|
||||
}
|
||||
if (treeNode) {
|
||||
sysDefStack.push_back(index);
|
||||
drawSysDefs(i.subDefs,accepted,sysDefStack);
|
||||
drawSysDefs(i.subDefs,accepted,sysDefStack,alreadyHover);
|
||||
sysDefStack.erase(sysDefStack.end()-1);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (isHovered) {
|
||||
if (isHovered && !alreadyHover) {
|
||||
alreadyHover=true;
|
||||
if (ImGui::BeginTooltip()) {
|
||||
std::map<DivSystem,int> chipCounts;
|
||||
std::vector<DivSystem> chips;
|
||||
|
|
@ -95,13 +96,33 @@ void FurnaceGUI::drawSysDefs(std::vector<FurnaceGUISysDef>& category, bool& acce
|
|||
}
|
||||
}
|
||||
|
||||
void findInSubs(std::vector<FurnaceGUISysDef>& where, std::vector<FurnaceGUISysDef>& newSongSearchResults, String lowerCase) {
|
||||
for (FurnaceGUISysDef& j: where) {
|
||||
if (!j.orig.empty()) {
|
||||
String lowerCase1=j.name;
|
||||
for (char& i: lowerCase1) {
|
||||
if (i>='A' && i<='Z') i+='a'-'A';
|
||||
}
|
||||
auto lastItem=std::remove_if(lowerCase1.begin(),lowerCase1.end(),[](char c) {
|
||||
return (c==' ' || c=='_' || c=='-');
|
||||
});
|
||||
lowerCase1.erase(lastItem,lowerCase1.end());
|
||||
if (lowerCase1.find(lowerCase)!=String::npos) {
|
||||
newSongSearchResults.push_back(j);
|
||||
newSongSearchResults[newSongSearchResults.size()-1].subDefs.clear();
|
||||
}
|
||||
}
|
||||
findInSubs(j.subDefs,newSongSearchResults,lowerCase);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
ImGui::Text("Choose a System!");
|
||||
ImGui::SetCursorPosX((ImGui::GetContentRegionAvail().x-ImGui::CalcTextSize(_("Choose a System!")).x)*0.5);
|
||||
ImGui::Text(_("Choose a System!"));
|
||||
ImGui::PopFont();
|
||||
|
||||
ImVec2 avail=ImGui::GetContentRegionAvail();
|
||||
|
|
@ -111,7 +132,7 @@ void FurnaceGUI::drawNewSong() {
|
|||
if (newSongFirstFrame)
|
||||
ImGui::SetKeyboardFocusHere();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputTextWithHint("##SysSearch","Search...",&newSongQuery)) {
|
||||
if (ImGui::InputTextWithHint("##SysSearch",_("Search..."),&newSongQuery)) {
|
||||
String lowerCase=newSongQuery;
|
||||
for (char& i: lowerCase) {
|
||||
if (i>='A' && i<='Z') i+='a'-'A';
|
||||
|
|
@ -123,26 +144,30 @@ void FurnaceGUI::drawNewSong() {
|
|||
newSongSearchResults.clear();
|
||||
for (FurnaceGUISysCategory& i: sysCategories) {
|
||||
for (FurnaceGUISysDef& j: i.systems) {
|
||||
String lowerCase1=j.name;
|
||||
for (char& i: lowerCase1) {
|
||||
if (i>='A' && i<='Z') i+='a'-'A';
|
||||
}
|
||||
auto lastItem=std::remove_if(lowerCase1.begin(),lowerCase1.end(),[](char c) {
|
||||
return (c==' ' || c=='_' || c=='-');
|
||||
});
|
||||
lowerCase1.erase(lastItem,lowerCase1.end());
|
||||
if (lowerCase1.find(lowerCase)!=String::npos) {
|
||||
newSongSearchResults.push_back(j);
|
||||
if (!j.orig.empty()) {
|
||||
String lowerCase1=j.name;
|
||||
for (char& i: lowerCase1) {
|
||||
if (i>='A' && i<='Z') i+='a'-'A';
|
||||
}
|
||||
auto lastItem=std::remove_if(lowerCase1.begin(),lowerCase1.end(),[](char c) {
|
||||
return (c==' ' || c=='_' || c=='-');
|
||||
});
|
||||
lowerCase1.erase(lastItem,lowerCase1.end());
|
||||
if (lowerCase1.find(lowerCase)!=String::npos) {
|
||||
newSongSearchResults.push_back(j);
|
||||
newSongSearchResults[newSongSearchResults.size()-1].subDefs.clear();
|
||||
}
|
||||
}
|
||||
findInSubs(j.subDefs,newSongSearchResults,lowerCase);
|
||||
}
|
||||
std::sort(newSongSearchResults.begin(),newSongSearchResults.end(),[](const FurnaceGUISysDef& a, const FurnaceGUISysDef& b) {
|
||||
return strcmp(a.name,b.name)<0;
|
||||
});
|
||||
auto lastItem=std::unique(newSongSearchResults.begin(),newSongSearchResults.end(),[](const FurnaceGUISysDef& a, const FurnaceGUISysDef& b) {
|
||||
return strcmp(a.name,b.name)==0;
|
||||
});
|
||||
newSongSearchResults.erase(lastItem,newSongSearchResults.end());
|
||||
}
|
||||
std::sort(newSongSearchResults.begin(),newSongSearchResults.end(),[](const FurnaceGUISysDef& a, const FurnaceGUISysDef& b) {
|
||||
return strcmp(a.name.c_str(),b.name.c_str())<0;
|
||||
});
|
||||
auto lastItem1=std::unique(newSongSearchResults.begin(),newSongSearchResults.end(),[](const FurnaceGUISysDef& a, const FurnaceGUISysDef& b) {
|
||||
return a.name==b.name;
|
||||
});
|
||||
newSongSearchResults.erase(lastItem1,newSongSearchResults.end());
|
||||
}
|
||||
if (ImGui::BeginTable("sysPicker",newSongQuery.empty()?2:1,ImGuiTableFlags_BordersInnerV)) {
|
||||
if (newSongQuery.empty()) {
|
||||
|
|
@ -153,9 +178,9 @@ void FurnaceGUI::drawNewSong() {
|
|||
if (newSongQuery.empty()) {
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Categories");
|
||||
ImGui::Text(_("Categories"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Systems");
|
||||
ImGui::Text(_("Systems"));
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
|
|
@ -184,13 +209,14 @@ void FurnaceGUI::drawNewSong() {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
if (newSongQuery.empty()) {
|
||||
ImGui::Text("no systems here yet!");
|
||||
ImGui::Text(_("no systems here yet!"));
|
||||
} else {
|
||||
ImGui::Text("no results");
|
||||
ImGui::Text(_("no results"));
|
||||
}
|
||||
} else {
|
||||
bool alreadyHover=false;
|
||||
sysDefStack.push_back(newSongQuery.empty()?newSongCategory:-1);
|
||||
drawSysDefs(category,accepted,sysDefStack);
|
||||
drawSysDefs(category,accepted,sysDefStack,alreadyHover);
|
||||
sysDefStack.erase(sysDefStack.end()-1);
|
||||
}
|
||||
ImGui::EndTable();
|
||||
|
|
@ -201,9 +227,9 @@ void FurnaceGUI::drawNewSong() {
|
|||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
if (ImGui::Button("I'm feeling lucky")) {
|
||||
if (ImGui::Button(_("I'm feeling lucky"))) {
|
||||
if (sysCategories.size()==0) {
|
||||
showError("no categories available! what in the world.");
|
||||
showError(_("no categories available! what in the world."));
|
||||
ImGui::CloseCurrentPopup();
|
||||
} else {
|
||||
int tries=0;
|
||||
|
|
@ -238,7 +264,7 @@ void FurnaceGUI::drawNewSong() {
|
|||
}
|
||||
|
||||
if (tries>=50) {
|
||||
showError("it appears you're extremely lucky today!");
|
||||
showError(_("it appears you're extremely lucky today!"));
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
|
@ -246,7 +272,7 @@ void FurnaceGUI::drawNewSong() {
|
|||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Cancel") || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
if (ImGui::Button(_("Cancel")) || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
|
|
@ -265,6 +291,7 @@ void FurnaceGUI::drawNewSong() {
|
|||
selEnd=SelectionPoint();
|
||||
cursor=SelectionPoint();
|
||||
updateWindowTitle();
|
||||
updateROMExportAvail();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ void FurnaceGUI::drawOrderButtons() {
|
|||
doAction(GUI_ACTION_ORDERS_ADD);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Add new order");
|
||||
ImGui::SetTooltip(_("Add new order"));
|
||||
}
|
||||
NEXT_BUTTON;
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ void FurnaceGUI::drawOrderButtons() {
|
|||
}
|
||||
popDestColor();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Remove order");
|
||||
ImGui::SetTooltip(_("Remove order"));
|
||||
}
|
||||
NEXT_BUTTON;
|
||||
|
||||
|
|
@ -134,7 +134,7 @@ void FurnaceGUI::drawOrderButtons() {
|
|||
doAction(GUI_ACTION_ORDERS_DEEP_CLONE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Duplicate order (right-click to deep clone)");
|
||||
ImGui::SetTooltip(_("Duplicate order (right-click to deep clone)"));
|
||||
}
|
||||
NEXT_BUTTON;
|
||||
|
||||
|
|
@ -143,7 +143,7 @@ void FurnaceGUI::drawOrderButtons() {
|
|||
doAction(GUI_ACTION_ORDERS_MOVE_UP);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Move order up");
|
||||
ImGui::SetTooltip(_("Move order up"));
|
||||
}
|
||||
NEXT_BUTTON;
|
||||
|
||||
|
|
@ -152,7 +152,7 @@ void FurnaceGUI::drawOrderButtons() {
|
|||
doAction(GUI_ACTION_ORDERS_MOVE_DOWN);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Move order down");
|
||||
ImGui::SetTooltip(_("Move order down"));
|
||||
}
|
||||
NEXT_BUTTON;
|
||||
|
||||
|
|
@ -164,7 +164,7 @@ void FurnaceGUI::drawOrderButtons() {
|
|||
doAction(GUI_ACTION_ORDERS_DEEP_CLONE_END);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Place copy of current order at end of song (right-click to deep clone)");
|
||||
ImGui::SetTooltip(_("Place copy of current order at end of song (right-click to deep clone)"));
|
||||
}
|
||||
NEXT_BUTTON;
|
||||
|
||||
|
|
@ -174,9 +174,9 @@ void FurnaceGUI::drawOrderButtons() {
|
|||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
if (changeAllOrders) {
|
||||
ImGui::SetTooltip("Order change mode: entire row");
|
||||
ImGui::SetTooltip(_("Order change mode: entire row"));
|
||||
} else {
|
||||
ImGui::SetTooltip("Order change mode: one");
|
||||
ImGui::SetTooltip(_("Order change mode: one"));
|
||||
}
|
||||
}
|
||||
NEXT_BUTTON;
|
||||
|
|
@ -202,13 +202,13 @@ void FurnaceGUI::drawOrderButtons() {
|
|||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
if (orderEditMode==3) {
|
||||
ImGui::SetTooltip("Order edit mode: Select and type (scroll vertically)");
|
||||
ImGui::SetTooltip(_("Order edit mode: Select and type (scroll vertically)"));
|
||||
} else if (orderEditMode==2) {
|
||||
ImGui::SetTooltip("Order edit mode: Select and type (scroll horizontally)");
|
||||
ImGui::SetTooltip(_("Order edit mode: Select and type (scroll horizontally)"));
|
||||
} else if (orderEditMode==1) {
|
||||
ImGui::SetTooltip("Order edit mode: Select and type (don't scroll)");
|
||||
ImGui::SetTooltip(_("Order edit mode: Select and type (don't scroll)"));
|
||||
} else {
|
||||
ImGui::SetTooltip("Order edit mode: Click to change");
|
||||
ImGui::SetTooltip(_("Order edit mode: Click to change"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -229,7 +229,7 @@ void FurnaceGUI::drawOrders() {
|
|||
} else {
|
||||
//ImGui::SetNextWindowSizeConstraints(ImVec2(440.0f*dpiScale,400.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||
}
|
||||
if (ImGui::Begin("Orders",&ordersOpen,globalWinFlags|ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse)) {
|
||||
if (ImGui::Begin("Orders",&ordersOpen,globalWinFlags|ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse,_("Orders"))) {
|
||||
if (ImGui::BeginTable("OrdColumn",(settings.orderButtonPos==0)?1:2,ImGuiTableFlags_BordersInnerV)) {
|
||||
if (settings.orderButtonPos==2) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch);
|
||||
|
|
@ -282,7 +282,7 @@ void FurnaceGUI::drawOrders() {
|
|||
for (int i=0; i<e->getTotalChannelCount(); i++) {
|
||||
if (!e->curSubSong->chanShow[i]) continue;
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s",e->getChannelShortName(i));
|
||||
ImGui::TextNoHashHide("%s",e->getChannelShortName(i));
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
for (int i=0; i<e->curSubSong->ordersLen; i++) {
|
||||
|
|
|
|||
|
|
@ -166,14 +166,14 @@ void FurnaceGUI::drawOsc() {
|
|||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,ImVec2(0,0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing,ImVec2(0,0));
|
||||
}
|
||||
if (ImGui::Begin("Oscilloscope",&oscOpen,globalWinFlags)) {
|
||||
if (ImGui::Begin("Oscilloscope",&oscOpen,globalWinFlags,_("Oscilloscope"))) {
|
||||
if (oscZoomSlider) {
|
||||
if (ImGui::VSliderFloat("##OscZoom",ImVec2(20.0f*dpiScale,ImGui::GetContentRegionAvail().y),&oscZoom,0.5,2.0)) {
|
||||
if (oscZoom<0.5) oscZoom=0.5;
|
||||
if (oscZoom>2.0) oscZoom=2.0;
|
||||
} rightClickable
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("zoom: %.2fx (%.1fdB)",oscZoom,20.0*log10(oscZoom*2.0));
|
||||
ImGui::SetTooltip(_("zoom: %.2fx (%.1fdB)"),oscZoom,20.0*log10(oscZoom*2.0));
|
||||
}
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Middle)) {
|
||||
oscZoom=0.5;
|
||||
|
|
@ -184,7 +184,7 @@ void FurnaceGUI::drawOsc() {
|
|||
if (oscWindowSize>100.0) oscWindowSize=100.0;
|
||||
} rightClickable
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("window size: %.1fms",oscWindowSize);
|
||||
ImGui::SetTooltip(_("window size: %.1fms"),oscWindowSize);
|
||||
}
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Middle)) {
|
||||
oscWindowSize=20.0;
|
||||
|
|
@ -216,15 +216,23 @@ void FurnaceGUI::drawOsc() {
|
|||
ImU32 guideColor=ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_GUIDE]);
|
||||
ImGui::ItemSize(size,style.FramePadding.y);
|
||||
if (ImGui::ItemAdd(rect,ImGui::GetID("wsDisplay"))) {
|
||||
dl->AddRectFilledMultiColor(
|
||||
inRect.Min,
|
||||
inRect.Max,
|
||||
ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_BG1]),
|
||||
ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_BG2]),
|
||||
ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_BG4]),
|
||||
ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_BG3]),
|
||||
settings.oscRoundedCorners?(8.0f*dpiScale):0.0f
|
||||
);
|
||||
if (safeMode || renderBackend==GUI_BACKEND_SOFTWARE) {
|
||||
dl->AddRectFilled(
|
||||
inRect.Min,
|
||||
inRect.Max,
|
||||
ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_BG4])
|
||||
);
|
||||
} else {
|
||||
dl->AddRectFilledMultiColor(
|
||||
inRect.Min,
|
||||
inRect.Max,
|
||||
ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_BG1]),
|
||||
ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_BG2]),
|
||||
ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_BG4]),
|
||||
ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_BG3]),
|
||||
settings.oscRoundedCorners?(8.0f*dpiScale):0.0f
|
||||
);
|
||||
}
|
||||
|
||||
dl->AddLine(
|
||||
ImLerp(rect.Min,rect.Max,ImVec2(0.0f,0.5f)),
|
||||
|
|
@ -367,14 +375,14 @@ void FurnaceGUI::drawOsc() {
|
|||
dl->Flags=prevFlags;
|
||||
|
||||
if (settings.oscBorder) {
|
||||
dl->AddRect(inRect.Min,inRect.Max,borderColor,settings.oscRoundedCorners?(8.0f*dpiScale):0.0f,0,1.5f*dpiScale);
|
||||
dl->AddRect(inRect.Min,inRect.Max,borderColor,(settings.oscRoundedCorners && !(safeMode || renderBackend==GUI_BACKEND_SOFTWARE))?(8.0f*dpiScale):0.0f,0,1.5f*dpiScale);
|
||||
}
|
||||
}
|
||||
if (oscZoomSlider && ImGui::IsItemHovered()) {
|
||||
float val=20.0*log10(2.0*fabs(0.5-((ImGui::GetMousePos().y-inRect.Min.y)/(inRect.Max.y-inRect.Min.y))));
|
||||
if (val>0.0f) val=0.0f;
|
||||
if (val<=-INFINITY) {
|
||||
ImGui::SetTooltip("(-Infinity)dB");
|
||||
ImGui::SetTooltip(_("(-Infinity)dB"));
|
||||
} else {
|
||||
ImGui::SetTooltip("%.1fdB",val);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,33 +32,29 @@ void FurnaceGUI::drawPatManager() {
|
|||
char id[1024];
|
||||
unsigned char isUsed[DIV_MAX_PATTERNS];
|
||||
bool isNull[DIV_MAX_PATTERNS];
|
||||
if (ImGui::Begin("Pattern Manager",&patManagerOpen,globalWinFlags)) {
|
||||
ImGui::Text("Global Tasks:");
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("De-duplicate patterns")) {
|
||||
if (ImGui::Begin("Pattern Manager",&patManagerOpen,globalWinFlags,_("Pattern Manager"))) {
|
||||
if (ImGui::Button(_("De-duplicate patterns"))) {
|
||||
e->lockEngine([this]() {
|
||||
e->curSubSong->optimizePatterns();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Re-arrange patterns")) {
|
||||
if (ImGui::Button(_("Re-arrange patterns"))) {
|
||||
e->lockEngine([this]() {
|
||||
e->curSubSong->rearrangePatterns();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Sort orders")) {
|
||||
if (ImGui::Button(_("Sort orders"))) {
|
||||
e->lockEngine([this]() {
|
||||
e->curSubSong->sortOrders();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Make patterns unique")) {
|
||||
if (ImGui::Button(_("Make patterns unique"))) {
|
||||
e->lockEngine([this]() {
|
||||
e->curSubSong->makePatUnique();
|
||||
});
|
||||
|
|
@ -104,9 +100,9 @@ void FurnaceGUI::drawPatManager() {
|
|||
ImGui::PushFont(mainFont);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_TEXT]);
|
||||
if (isNull[k]) {
|
||||
ImGui::SetTooltip("Pattern %.2X\n- not allocated",k);
|
||||
ImGui::SetTooltip(_("Pattern %.2X\n- not allocated"),k);
|
||||
} else {
|
||||
ImGui::SetTooltip("Pattern %.2X\n- use count: %d (%.0f%%)\n\nright-click to erase",k,isUsed[k],100.0*(double)isUsed[k]/(double)e->curSubSong->ordersLen);
|
||||
ImGui::SetTooltip(_("Pattern %.2X\n- use count: %d (%.0f%%)\n\nright-click to erase"),k,isUsed[k],100.0*(double)isUsed[k]/(double)e->curSubSong->ordersLen);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopFont();
|
||||
|
|
|
|||
|
|
@ -191,7 +191,6 @@ inline void FurnaceGUI::patternRow(int i, bool isPlaying, float lineHeight, int
|
|||
ImGui::PushStyleColor(ImGuiCol_HeaderActive,uiColors[GUI_COLOR_PATTERN_CURSOR_ACTIVE]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_CURSOR_HOVER]);
|
||||
ImGui::Selectable(id,true,ImGuiSelectableFlags_NoPadWithHalfSpacing,noteCellSize);
|
||||
demandX=ImGui::GetCursorPosX();
|
||||
ImGui::PopStyleColor(3);
|
||||
} else {
|
||||
if (selectedNote) ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_SELECTION]);
|
||||
|
|
@ -235,7 +234,6 @@ inline void FurnaceGUI::patternRow(int i, bool isPlaying, float lineHeight, int
|
|||
ImGui::PushStyleColor(ImGuiCol_HeaderActive,uiColors[GUI_COLOR_PATTERN_CURSOR_ACTIVE]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_CURSOR_HOVER]);
|
||||
ImGui::Selectable(id,true,ImGuiSelectableFlags_NoPadWithHalfSpacing,insCellSize);
|
||||
demandX=ImGui::GetCursorPosX();
|
||||
ImGui::PopStyleColor(3);
|
||||
} else {
|
||||
if (selectedIns) ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_SELECTION]);
|
||||
|
|
@ -273,7 +271,6 @@ inline void FurnaceGUI::patternRow(int i, bool isPlaying, float lineHeight, int
|
|||
ImGui::PushStyleColor(ImGuiCol_HeaderActive,uiColors[GUI_COLOR_PATTERN_CURSOR_ACTIVE]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_CURSOR_HOVER]);
|
||||
ImGui::Selectable(id,true,ImGuiSelectableFlags_NoPadWithHalfSpacing,volCellSize);
|
||||
demandX=ImGui::GetCursorPosX();
|
||||
ImGui::PopStyleColor(3);
|
||||
} else {
|
||||
if (selectedVol) ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_SELECTION]);
|
||||
|
|
@ -326,7 +323,6 @@ inline void FurnaceGUI::patternRow(int i, bool isPlaying, float lineHeight, int
|
|||
ImGui::PushStyleColor(ImGuiCol_HeaderActive,uiColors[GUI_COLOR_PATTERN_CURSOR_ACTIVE]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_CURSOR_HOVER]);
|
||||
ImGui::Selectable(id,true,ImGuiSelectableFlags_NoPadWithHalfSpacing,effectCellSize);
|
||||
demandX=ImGui::GetCursorPosX();
|
||||
ImGui::PopStyleColor(3);
|
||||
} else {
|
||||
if (selectedEffect) ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_SELECTION]);
|
||||
|
|
@ -356,7 +352,6 @@ inline void FurnaceGUI::patternRow(int i, bool isPlaying, float lineHeight, int
|
|||
ImGui::PushStyleColor(ImGuiCol_HeaderActive,uiColors[GUI_COLOR_PATTERN_CURSOR_ACTIVE]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_CURSOR_HOVER]);
|
||||
ImGui::Selectable(id,true,ImGuiSelectableFlags_NoPadWithHalfSpacing,effectValCellSize);
|
||||
demandX=ImGui::GetCursorPosX();
|
||||
ImGui::PopStyleColor(3);
|
||||
} else {
|
||||
if (selectedEffectVal) ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_SELECTION]);
|
||||
|
|
@ -407,7 +402,6 @@ void FurnaceGUI::drawPattern() {
|
|||
}
|
||||
}
|
||||
}
|
||||
demandX=0;
|
||||
sel1=selStart;
|
||||
sel2=selEnd;
|
||||
if (sel2.y<sel1.y) {
|
||||
|
|
@ -436,7 +430,7 @@ void FurnaceGUI::drawPattern() {
|
|||
ImGui::SetNextWindowPos(patWindowPos);
|
||||
ImGui::SetNextWindowSize(patWindowSize);
|
||||
}
|
||||
if (ImGui::Begin("Pattern",&patternOpen,globalWinFlags|(settings.avoidRaisingPattern?ImGuiWindowFlags_NoBringToFrontOnFocus:0)|(settings.cursorFollowsWheel?ImGuiWindowFlags_NoScrollWithMouse:0))) {
|
||||
if (ImGui::Begin("Pattern",&patternOpen,globalWinFlags|(settings.avoidRaisingPattern?ImGuiWindowFlags_NoBringToFrontOnFocus:0)|(settings.cursorFollowsWheel?ImGuiWindowFlags_NoScrollWithMouse:0),_("Pattern"))) {
|
||||
if (!mobileUI) {
|
||||
patWindowPos=ImGui::GetWindowPos();
|
||||
patWindowSize=ImGui::GetWindowSize();
|
||||
|
|
@ -471,7 +465,7 @@ void FurnaceGUI::drawPattern() {
|
|||
ImDrawList* tdl=NULL;
|
||||
|
||||
if (chans<1) {
|
||||
ImGui::Text("there aren't any channels to show.");
|
||||
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];
|
||||
|
|
@ -495,7 +489,7 @@ void FurnaceGUI::drawPattern() {
|
|||
ImGui::OpenPopup("PatternOpt");
|
||||
}
|
||||
if (ImGui::IsItemHovered() && !mobileUI) {
|
||||
ImGui::SetTooltip("click for pattern options (effect columns/pattern names/visualizer)");
|
||||
ImGui::SetTooltip(_("click for pattern options (effect columns/pattern names/visualizer)"));
|
||||
}
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
|
||||
fancyPattern=!fancyPattern;
|
||||
|
|
@ -507,12 +501,12 @@ void FurnaceGUI::drawPattern() {
|
|||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding,origWinPadding);
|
||||
ImGui::PushFont(mainFont);
|
||||
if (ImGui::BeginPopup("PatternOpt",ImGuiWindowFlags_NoMove|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings)) {
|
||||
ImGui::Text("Options:");
|
||||
ImGui::Text(_("Options:"));
|
||||
ImGui::Indent();
|
||||
ImGui::Checkbox("Effect columns/collapse",&patExtraButtons);
|
||||
ImGui::Checkbox("Pattern names",&patChannelNames);
|
||||
ImGui::Checkbox("Channel group hints",&patChannelPairs);
|
||||
if (ImGui::Checkbox("Visualizer",&fancyPattern)) {
|
||||
ImGui::Checkbox(_("Effect columns/collapse"),&patExtraButtons);
|
||||
ImGui::Checkbox(_("Pattern names"),&patChannelNames);
|
||||
ImGui::Checkbox(_("Channel group hints"),&patChannelPairs);
|
||||
if (ImGui::Checkbox(_("Visualizer"),&fancyPattern)) {
|
||||
inhibitMenu=true;
|
||||
e->enableCommandStream(fancyPattern);
|
||||
e->getCommandStream(cmdStream);
|
||||
|
|
@ -520,19 +514,19 @@ void FurnaceGUI::drawPattern() {
|
|||
}
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::Text("Channel status:");
|
||||
ImGui::Text(_("Channel status:"));
|
||||
ImGui::Indent();
|
||||
if (ImGui::RadioButton("No##_PCS0",patChannelHints==0)) {
|
||||
if (ImGui::RadioButton(_("No##_PCS0"),patChannelHints==0)) {
|
||||
patChannelHints=0;
|
||||
}
|
||||
if (ImGui::RadioButton("Yes##_PCS1",patChannelHints==1)) {
|
||||
if (ImGui::RadioButton(_("Yes##_PCS1"),patChannelHints==1)) {
|
||||
patChannelHints=1;
|
||||
}
|
||||
/*
|
||||
if (ImGui::RadioButton("Regular##_PCS2",patChannelHints==2)) {
|
||||
if (ImGui::RadioButton(_("Regular##_PCS2"),patChannelHints==2)) {
|
||||
patChannelHints=2;
|
||||
}
|
||||
if (ImGui::RadioButton("Detailed##_PCS3",patChannelHints==3)) {
|
||||
if (ImGui::RadioButton(_("Detailed##_PCS3"),patChannelHints==3)) {
|
||||
patChannelHints=3;
|
||||
}*/
|
||||
ImGui::Unindent();
|
||||
|
|
@ -692,7 +686,7 @@ void FurnaceGUI::drawPattern() {
|
|||
bool hovered=ImGui::ItemHoverable(rect,ImGui::GetID(chanID),0);
|
||||
ImU32 col=(hovered || (mobileUI && ImGui::IsMouseDown(ImGuiMouseButton_Left)))?ImGui::GetColorU32(ImGuiCol_HeaderHovered):ImGui::GetColorU32(ImGuiCol_Header);
|
||||
dl->AddRectFilled(rect.Min,rect.Max,col);
|
||||
dl->AddText(ImVec2(minLabelArea.x,rect.Min.y),ImGui::GetColorU32(channelTextColor(i)),chanID);
|
||||
dl->AddTextNoHashHide(ImVec2(minLabelArea.x,rect.Min.y),ImGui::GetColorU32(channelTextColor(i)),chanID);
|
||||
}
|
||||
break;
|
||||
case 1: { // line
|
||||
|
|
@ -713,7 +707,7 @@ void FurnaceGUI::drawPattern() {
|
|||
));
|
||||
dl->AddRectFilledMultiColor(rect.Min,rect.Max,fadeCol0,fadeCol0,fadeCol,fadeCol);
|
||||
dl->AddLine(ImVec2(rect.Min.x,rect.Max.y),ImVec2(rect.Max.x,rect.Max.y),ImGui::GetColorU32(chanHeadBase),2.0f*dpiScale);
|
||||
dl->AddText(ImVec2(minLabelArea.x,rect.Min.y+3.0*dpiScale),ImGui::GetColorU32(channelTextColor(i)),chanID);
|
||||
dl->AddTextNoHashHide(ImVec2(minLabelArea.x,rect.Min.y+3.0*dpiScale),ImGui::GetColorU32(channelTextColor(i)),chanID);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -740,14 +734,14 @@ void FurnaceGUI::drawPattern() {
|
|||
rMax.x-=3.0f*dpiScale;
|
||||
rMax.y-=6.0f*dpiScale;
|
||||
dl->AddRectFilledMultiColor(rMin,rMax,fadeCol0,fadeCol0,fadeCol,fadeCol,4.0f*dpiScale);
|
||||
dl->AddText(ImVec2(minLabelArea.x,rect.Min.y+6.0*dpiScale),ImGui::GetColorU32(channelTextColor(i)),chanID);
|
||||
dl->AddTextNoHashHide(ImVec2(minLabelArea.x,rect.Min.y+6.0*dpiScale),ImGui::GetColorU32(channelTextColor(i)),chanID);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3: // split button
|
||||
ImGui::Dummy(ImVec2(1.0f,2.0f*dpiScale));
|
||||
//ImGui::SetCursorPosX(minLabelArea.x);
|
||||
ImGui::TextUnformatted(chanID);
|
||||
ImGui::TextNoHashHide("%s",chanID);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushFont(mainFont);
|
||||
ImGui::SmallButton(muted?ICON_FA_VOLUME_OFF:ICON_FA_VOLUME_UP);
|
||||
|
|
@ -770,7 +764,7 @@ void FurnaceGUI::drawPattern() {
|
|||
rMax.x-=3.0f*dpiScale;
|
||||
rMax.y-=3.0f*dpiScale;
|
||||
dl->AddRect(rMin,rMax,fadeCol,0.0f,2.0*dpiScale);
|
||||
dl->AddText(ImVec2(minLabelArea.x,rect.Min.y+3.0*dpiScale),ImGui::GetColorU32(channelTextColor(i)),chanID);
|
||||
dl->AddTextNoHashHide(ImVec2(minLabelArea.x,rect.Min.y+3.0*dpiScale),ImGui::GetColorU32(channelTextColor(i)),chanID);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -791,7 +785,7 @@ void FurnaceGUI::drawPattern() {
|
|||
rMax.x-=3.0f*dpiScale;
|
||||
rMax.y-=3.0f*dpiScale;
|
||||
dl->AddRect(rMin,rMax,fadeCol,4.0f*dpiScale,ImDrawFlags_RoundCornersAll,2.0*dpiScale);
|
||||
dl->AddText(ImVec2(minLabelArea.x,rect.Min.y+3.0*dpiScale),ImGui::GetColorU32(channelTextColor(i)),chanID);
|
||||
dl->AddTextNoHashHide(ImVec2(minLabelArea.x,rect.Min.y+3.0*dpiScale),ImGui::GetColorU32(channelTextColor(i)),chanID);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -1167,11 +1161,41 @@ void FurnaceGUI::drawPattern() {
|
|||
ImGui::EndDisabled();
|
||||
ImGui::PopStyleVar();
|
||||
if (demandScrollX) {
|
||||
int totalDemand=demandX-ImGui::GetScrollX();
|
||||
if (totalDemand<80) {
|
||||
ImGui::SetScrollX(demandX-200*dpiScale);
|
||||
} else if (totalDemand>(ImGui::GetWindowWidth()-200*dpiScale)) {
|
||||
ImGui::SetScrollX(demandX+200*dpiScale);
|
||||
float finalX=-fourChars.x;
|
||||
// manually calculate X scroll
|
||||
for (int i=0; i<=cursor.xCoarse; i++) {
|
||||
int fine=(i==cursor.xCoarse)?cursor.xFine:9999;
|
||||
if (!e->curSubSong->chanShow[i]) continue;
|
||||
|
||||
finalX+=noteCellSize.x;
|
||||
// ins
|
||||
if (fine==0) break;
|
||||
if (e->curSubSong->chanCollapse[i]<3) {
|
||||
finalX+=insCellSize.x;
|
||||
}
|
||||
// vol
|
||||
if (fine==1) break;
|
||||
if (e->curSubSong->chanCollapse[i]<2) {
|
||||
finalX+=volCellSize.x;
|
||||
}
|
||||
// effects
|
||||
if (fine==2) break;
|
||||
if (e->curSubSong->chanCollapse[i]<1) {
|
||||
for (int j=0; j<MIN(fine-2,e->curPat[i].effectCols*2); j++) {
|
||||
if (j&1) {
|
||||
finalX+=effectValCellSize.x;
|
||||
} else {
|
||||
finalX+=effectCellSize.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
float totalDemand=finalX-ImGui::GetScrollX();
|
||||
float availWidth=ImGui::GetWindowWidth();
|
||||
if (totalDemand<(availWidth*0.25f)) {
|
||||
ImGui::SetScrollX(finalX-availWidth*0.25f);
|
||||
} else if (totalDemand>(availWidth*0.7f)) {
|
||||
ImGui::SetScrollX(finalX-availWidth*0.7f);
|
||||
}
|
||||
demandScrollX=false;
|
||||
}
|
||||
|
|
@ -1393,11 +1417,11 @@ void FurnaceGUI::drawPattern() {
|
|||
if (tdl!=NULL && failedNoteOn) {
|
||||
ImVec2 winCenter=ImGui::GetWindowPos()+ImGui::GetWindowSize()*0.5f;
|
||||
ImGui::PushFont(bigFont);
|
||||
ImVec2 warnHeadSize=ImGui::CalcTextSize("WARNING!!");
|
||||
ImVec2 warnHeadSize=ImGui::CalcTextSize(_("WARNING!!"));
|
||||
ImGui::PopFont();
|
||||
ImVec2 warnTextSize1=ImGui::CalcTextSize("this instrument cannot be previewed because");
|
||||
ImVec2 warnTextSize2=ImGui::CalcTextSize("none of the chips can play it");
|
||||
ImVec2 warnTextSize3=ImGui::CalcTextSize("your instrument is in peril!! be careful...");
|
||||
ImVec2 warnTextSize1=ImGui::CalcTextSize(_("this instrument cannot be previewed because"));
|
||||
ImVec2 warnTextSize2=ImGui::CalcTextSize(_("none of the chips can play it"));
|
||||
ImVec2 warnTextSize3=ImGui::CalcTextSize(_("your instrument is in peril!! be careful..."));
|
||||
|
||||
float maxTextSize=warnHeadSize.x;
|
||||
if (warnTextSize1.x>maxTextSize) maxTextSize=warnTextSize1.x;
|
||||
|
|
@ -1425,28 +1449,28 @@ void FurnaceGUI::drawPattern() {
|
|||
MAX(1,40*dpiScale),
|
||||
ImVec2(winCenter.x-warnHeadSize.x*0.5,whereY),
|
||||
ImGui::GetColorU32(ImGuiCol_Text),
|
||||
"WARNING!!"
|
||||
_("WARNING!!")
|
||||
);
|
||||
whereY+=warnHeadSize.y;
|
||||
|
||||
tdl->AddText(
|
||||
ImVec2(winCenter.x-warnTextSize1.x*0.5,whereY),
|
||||
ImGui::GetColorU32(ImGuiCol_Text),
|
||||
"this instrument cannot be previewed because"
|
||||
_("this instrument cannot be previewed because")
|
||||
);
|
||||
whereY+=warnTextSize1.y;
|
||||
|
||||
tdl->AddText(
|
||||
ImVec2(winCenter.x-warnTextSize2.x*0.5,whereY),
|
||||
ImGui::GetColorU32(ImGuiCol_Text),
|
||||
"none of the chips can play it"
|
||||
_("none of the chips can play it")
|
||||
);
|
||||
whereY+=warnTextSize2.y;
|
||||
|
||||
tdl->AddText(
|
||||
ImVec2(winCenter.x-warnTextSize3.x*0.5,whereY),
|
||||
ImGui::GetColorU32(ImGuiCol_Text),
|
||||
"your instrument is in peril!! be careful..."
|
||||
_("your instrument is in peril!! be careful...")
|
||||
);
|
||||
whereY+=warnTextSize3.y;
|
||||
}
|
||||
|
|
@ -1735,7 +1759,5 @@ void FurnaceGUI::drawPattern() {
|
|||
}
|
||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_PATTERN;
|
||||
ImGui::End();
|
||||
//int delta1=SDL_GetPerformanceCounter();
|
||||
//logV("render time: %dµs",(delta1-delta0)/(SDL_GetPerformanceFrequency()/1000000));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ void FurnaceGUI::drawPiano() {
|
|||
ImGui::SetNextWindowPos(ImVec2(patWindowPos.x,patWindowPos.y+patWindowSize.y));
|
||||
ImGui::SetNextWindowSize(portrait?ImVec2(canvasW,0.4*canvasW):ImVec2(canvasW-(0.16*canvasH),0.3*canvasH));
|
||||
}
|
||||
if (ImGui::Begin("Piano",&pianoOpen,((pianoOptions)?0:ImGuiWindowFlags_NoTitleBar)|ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags)) {
|
||||
if (ImGui::Begin("Piano",&pianoOpen,((pianoOptions)?0:ImGuiWindowFlags_NoTitleBar)|ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags,_("Piano"))) {
|
||||
bool oldPianoKeyPressed[180];
|
||||
memcpy(oldPianoKeyPressed,pianoKeyPressed,180*sizeof(bool));
|
||||
memset(pianoKeyPressed,0,180*sizeof(bool));
|
||||
|
|
@ -100,38 +100,38 @@ void FurnaceGUI::drawPiano() {
|
|||
ImGui::SameLine();
|
||||
ImGui::Button(ICON_FA_ELLIPSIS_V "##PianoOptions",optionSize);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Options");
|
||||
ImGui::SetTooltip(_("Options"));
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("PianoOptions",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
ImGui::Text("Key layout:");
|
||||
ImGui::Text(_("Key layout:"));
|
||||
ImGui::Indent();
|
||||
if (ImGui::RadioButton("Automatic",pianoView==PIANO_LAYOUT_AUTOMATIC)) {
|
||||
if (ImGui::RadioButton(_("Automatic"),pianoView==PIANO_LAYOUT_AUTOMATIC)) {
|
||||
pianoView=PIANO_LAYOUT_AUTOMATIC;
|
||||
}
|
||||
if (ImGui::RadioButton("Standard",pianoView==PIANO_LAYOUT_STANDARD)) {
|
||||
if (ImGui::RadioButton(_("Standard"),pianoView==PIANO_LAYOUT_STANDARD)) {
|
||||
pianoView=PIANO_LAYOUT_STANDARD;
|
||||
}
|
||||
if (ImGui::RadioButton("Continuous",pianoView==PIANO_LAYOUT_CONTINUOUS)) {
|
||||
if (ImGui::RadioButton(_("Continuous"),pianoView==PIANO_LAYOUT_CONTINUOUS)) {
|
||||
pianoView=PIANO_LAYOUT_CONTINUOUS;
|
||||
}
|
||||
ImGui::Unindent();
|
||||
ImGui::Text("Value input pad:");
|
||||
ImGui::Text(_("Value input pad:"));
|
||||
ImGui::Indent();
|
||||
if (ImGui::RadioButton("Disabled",pianoInputPadMode==PIANO_INPUT_PAD_DISABLE)) {
|
||||
if (ImGui::RadioButton(_("Disabled"),pianoInputPadMode==PIANO_INPUT_PAD_DISABLE)) {
|
||||
pianoInputPadMode=PIANO_INPUT_PAD_DISABLE;
|
||||
}
|
||||
if (ImGui::RadioButton("Replace piano",pianoInputPadMode==PIANO_INPUT_PAD_REPLACE)) {
|
||||
if (ImGui::RadioButton(_("Replace piano"),pianoInputPadMode==PIANO_INPUT_PAD_REPLACE)) {
|
||||
pianoInputPadMode=PIANO_INPUT_PAD_REPLACE;
|
||||
}
|
||||
if (ImGui::RadioButton("Split (automatic)",pianoInputPadMode==PIANO_INPUT_PAD_SPLIT_AUTO)) {
|
||||
if (ImGui::RadioButton(_("Split (automatic)"),pianoInputPadMode==PIANO_INPUT_PAD_SPLIT_AUTO)) {
|
||||
pianoInputPadMode=PIANO_INPUT_PAD_SPLIT_AUTO;
|
||||
}
|
||||
if (ImGui::RadioButton("Split (always visible)",pianoInputPadMode==PIANO_INPUT_PAD_SPLIT_VISIBLE)) {
|
||||
if (ImGui::RadioButton(_("Split (always visible)"),pianoInputPadMode==PIANO_INPUT_PAD_SPLIT_VISIBLE)) {
|
||||
pianoInputPadMode=PIANO_INPUT_PAD_SPLIT_VISIBLE;
|
||||
}
|
||||
ImGui::Unindent();
|
||||
ImGui::Checkbox("Share play/edit offset/range",&pianoSharePosition);
|
||||
ImGui::Checkbox("Read-only (can't input notes)",&pianoReadonly);
|
||||
ImGui::Checkbox(_("Share play/edit offset/range"),&pianoSharePosition);
|
||||
ImGui::Checkbox(_("Read-only (can't input notes)"),&pianoReadonly);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
|
||||
#include "../ta-utils.h"
|
||||
|
||||
struct FurnacePlotArrayGetterData
|
||||
{
|
||||
const float* Values;
|
||||
|
|
@ -183,7 +185,7 @@ void PlotNoLerp(const char* label, const float* values, int values_count, int va
|
|||
PlotNoLerpEx(ImGuiPlotType_Lines, label, &Plot_ArrayGetter, (void*)&data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size);
|
||||
}
|
||||
|
||||
int PlotBitfieldEx(const char* label, int (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char** overlay_text, int bits, ImVec2 frame_size, const bool* values_highlight, ImVec4 highlightColor)
|
||||
int PlotBitfieldEx(const char* label, int (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char** overlay_text, int bits, ImVec2 frame_size, const bool* values_highlight, ImVec4 highlightColor, ImVec4 color)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
|
|
@ -232,8 +234,8 @@ int PlotBitfieldEx(const char* label, int (*values_getter)(void* data, int idx),
|
|||
|
||||
float t0 = 0.0f;
|
||||
ImVec2 tp0 = ImVec2( t0, 0.0f ); // Point in the normalized space of our target rectangle
|
||||
const ImU32 col_base = ImGui::GetColorU32(ImGuiCol_PlotHistogram);
|
||||
const ImU32 col_hovered = ImGui::GetColorU32(ImGuiCol_PlotHistogramHovered);
|
||||
const ImU32 col_base = ImGui::GetColorU32(color);
|
||||
const ImU32 col_hovered = ImGui::GetColorU32(color);
|
||||
|
||||
for (int n = 0; n < res_w; n++)
|
||||
{
|
||||
|
|
@ -270,12 +272,13 @@ int PlotBitfieldEx(const char* label, int (*values_getter)(void* data, int idx),
|
|||
float lineHeight=ImGui::GetTextLineHeight()/2.0;
|
||||
for (int i=0; i<bits && overlay_text[i]; i++) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,ImVec4(0,0,0,1.0f));
|
||||
ImGui::RenderTextClipped(ImVec2(frame_bb.Min.x-1, frame_bb.Min.y-lineHeight-1), ImVec2(frame_bb.Max.x-1,frame_bb.Max.y+lineHeight-1), overlay_text[i], NULL, NULL, ImVec2(0.0f, (0.5+double(bits-1-i))/double(bits)));
|
||||
ImGui::RenderTextClipped(ImVec2(frame_bb.Min.x-1, frame_bb.Min.y-lineHeight+1), ImVec2(frame_bb.Max.x-1,frame_bb.Max.y+lineHeight+1), overlay_text[i], NULL, NULL, ImVec2(0.0f, (0.5+double(bits-1-i))/double(bits)));
|
||||
ImGui::RenderTextClipped(ImVec2(frame_bb.Min.x+1, frame_bb.Min.y-lineHeight-1), ImVec2(frame_bb.Max.x+1,frame_bb.Max.y+lineHeight-1), overlay_text[i], NULL, NULL, ImVec2(0.0f, (0.5+double(bits-1-i))/double(bits)));
|
||||
ImGui::RenderTextClipped(ImVec2(frame_bb.Min.x+1, frame_bb.Min.y-lineHeight+1), ImVec2(frame_bb.Max.x+1,frame_bb.Max.y+lineHeight+1), overlay_text[i], NULL, NULL, ImVec2(0.0f, (0.5+double(bits-1-i))/double(bits)));
|
||||
const char* text=_(overlay_text[i]);
|
||||
ImGui::RenderTextClipped(ImVec2(frame_bb.Min.x-1, frame_bb.Min.y-lineHeight-1), ImVec2(frame_bb.Max.x-1,frame_bb.Max.y+lineHeight-1), text, NULL, NULL, ImVec2(0.0f, (0.5+double(bits-1-i))/double(bits)));
|
||||
ImGui::RenderTextClipped(ImVec2(frame_bb.Min.x-1, frame_bb.Min.y-lineHeight+1), ImVec2(frame_bb.Max.x-1,frame_bb.Max.y+lineHeight+1), text, NULL, NULL, ImVec2(0.0f, (0.5+double(bits-1-i))/double(bits)));
|
||||
ImGui::RenderTextClipped(ImVec2(frame_bb.Min.x+1, frame_bb.Min.y-lineHeight-1), ImVec2(frame_bb.Max.x+1,frame_bb.Max.y+lineHeight-1), text, NULL, NULL, ImVec2(0.0f, (0.5+double(bits-1-i))/double(bits)));
|
||||
ImGui::RenderTextClipped(ImVec2(frame_bb.Min.x+1, frame_bb.Min.y-lineHeight+1), ImVec2(frame_bb.Max.x+1,frame_bb.Max.y+lineHeight+1), text, NULL, NULL, ImVec2(0.0f, (0.5+double(bits-1-i))/double(bits)));
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y-lineHeight), ImVec2(frame_bb.Max.x,frame_bb.Max.y+lineHeight), overlay_text[i], NULL, NULL, ImVec2(0.0f, (0.5+double(bits-1-i))/double(bits)));
|
||||
ImGui::RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y-lineHeight), ImVec2(frame_bb.Max.x,frame_bb.Max.y+lineHeight), text, NULL, NULL, ImVec2(0.0f, (0.5+double(bits-1-i))/double(bits)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -287,10 +290,10 @@ int PlotBitfieldEx(const char* label, int (*values_getter)(void* data, int idx),
|
|||
return idx_hovered;
|
||||
}
|
||||
|
||||
void PlotBitfield(const char* label, const int* values, int values_count, int values_offset, const char** overlay_text, int bits, ImVec2 graph_size, int stride, const bool* values_highlight, ImVec4 highlightColor)
|
||||
void PlotBitfield(const char* label, const int* values, int values_count, int values_offset, const char** overlay_text, int bits, ImVec2 graph_size, int stride, const bool* values_highlight, ImVec4 highlightColor, ImVec4 color)
|
||||
{
|
||||
FurnacePlotIntArrayGetterData data(values, stride);
|
||||
PlotBitfieldEx(label, &Plot_IntArrayGetter, (void*)&data, values_count, values_offset, overlay_text, bits, graph_size, values_highlight, highlightColor);
|
||||
PlotBitfieldEx(label, &Plot_IntArrayGetter, (void*)&data, values_count, values_offset, overlay_text, bits, graph_size, values_highlight, highlightColor, color);
|
||||
}
|
||||
|
||||
int PlotCustomEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_display_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 frame_size, ImVec4 color, int highlight, std::string (*hoverFunc)(int,float,void*), void* hoverFuncUser, bool blockMode, std::string (*guideFunc)(float), const bool* values_highlight, ImVec4 highlightColor)
|
||||
|
|
|
|||
|
|
@ -21,5 +21,5 @@
|
|||
#include "../pch.h"
|
||||
|
||||
void PlotNoLerp(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float));
|
||||
void PlotBitfield(const char* label, const int* values, int values_count, int values_offset = 0, const char** overlay_text = NULL, int bits = 8, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float), const bool* values_highlight = NULL, ImVec4 highlightColor = ImVec4(1.0f,1.0f,1.0f,1.0f));
|
||||
void PlotBitfield(const char* label, const int* values, int values_count, int values_offset = 0, const char** overlay_text = NULL, int bits = 8, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float), const bool* values_highlight = NULL, ImVec4 highlightColor = ImVec4(1.0f,1.0f,1.0f,1.0f), ImVec4 color = ImVec4(1.0f,1.0f,1.0f,1.0f));
|
||||
void PlotCustom(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float), ImVec4 fgColor = ImVec4(1.0f,1.0f,1.0f,1.0f), int highlight = 0, std::string (*hoverFunc)(int,float,void*) = NULL, void* hoverFuncUser=NULL, bool blockMode=false, std::string (*guideFunc)(float) = NULL, const bool* values_highlight = NULL, ImVec4 highlightColor = ImVec4(1.0f,1.0f,1.0f,1.0f));
|
||||
|
|
|
|||
|
|
@ -19,7 +19,11 @@
|
|||
|
||||
#include "gui.h"
|
||||
#include "../baseutils.h"
|
||||
#include "../fileutils.h"
|
||||
#include <fmt/printf.h>
|
||||
#include "IconsFontAwesome4.h"
|
||||
#include <imgui.h>
|
||||
#include "misc/cpp/imgui_stdlib.h"
|
||||
|
||||
// add system configurations here.
|
||||
// every entry is written in the following format:
|
||||
|
|
@ -137,12 +141,15 @@ void FurnaceGUI::initSystemPresets() {
|
|||
}
|
||||
);
|
||||
ENTRY(
|
||||
"Game Boy Advance", {}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Game Boy Advance (no software mixing)", {
|
||||
CH(DIV_SYSTEM_GB, 1.0f, 0, "chipType=3"),
|
||||
CH(DIV_SYSTEM_GBA_DMA, 0.5f, 0, ""),
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
SUB_ENTRY(
|
||||
"Game Boy Advance (with MinMod)", {
|
||||
CH(DIV_SYSTEM_GB, 1.0f, 0, "chipType=3"),
|
||||
CH(DIV_SYSTEM_GBA_MINMOD, 0.5f, 0, ""),
|
||||
|
|
@ -212,6 +219,19 @@ void FurnaceGUI::initSystemPresets() {
|
|||
CH(DIV_SYSTEM_SNES, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Super Game Boy", {
|
||||
CH(DIV_SYSTEM_GB, 1.0f, 0, "customClock=4295455"),
|
||||
CH(DIV_SYSTEM_SNES, 1.0f, 0, "")
|
||||
},
|
||||
"tickRate=61.44697015935724"
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Super Game Boy 2", {
|
||||
CH(DIV_SYSTEM_GB, 1.0f, 0, ""),
|
||||
CH(DIV_SYSTEM_SNES, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"Mattel Intellivision", {
|
||||
CH(DIV_SYSTEM_AY8910, 1.0f, 0, "chipType=3")
|
||||
|
|
@ -237,12 +257,23 @@ void FurnaceGUI::initSystemPresets() {
|
|||
CH(DIV_SYSTEM_TIA, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Atari 2600/7800 (with software pitch driver)", {
|
||||
CH(DIV_SYSTEM_TIA, 1.0f, 0, "softwarePitch=1")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"Atari 7800 + Ballblazer/Commando", {
|
||||
CH(DIV_SYSTEM_TIA, 1.0f, 0, ""),
|
||||
CH(DIV_SYSTEM_POKEY, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Atari 7800 (with software pitch driver) + Ballblazer/Commando", {
|
||||
CH(DIV_SYSTEM_TIA, 1.0f, 0, "softwarePitch=1"),
|
||||
CH(DIV_SYSTEM_POKEY, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"Atari Lynx", {
|
||||
CH(DIV_SYSTEM_LYNX, 1.0f, 0, "")
|
||||
|
|
@ -488,6 +519,11 @@ void FurnaceGUI::initSystemPresets() {
|
|||
) // variable rate, Mono DAC
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"NEC PC-6001", {
|
||||
CH(DIV_SYSTEM_AY8910, 1.0f, 0, "customClock=3993600")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"NEC PC-88", {}
|
||||
);
|
||||
|
|
@ -1017,7 +1053,7 @@ void FurnaceGUI::initSystemPresets() {
|
|||
);
|
||||
SUB_ENTRY(
|
||||
"Tandy 1000", {
|
||||
CH(DIV_SYSTEM_SMS, 1.0f, 0, "chipType=5"), // NCR 8496 or SN76496 or Tandy PSSJ(with 8 bit DAC)
|
||||
CH(DIV_SYSTEM_SMS, 1.0f, 0, "chipType=5"), // NCR 8496 or SN76496 or Tandy PSSJ (with 8 bit DAC)
|
||||
CH(DIV_SYSTEM_PCSPKR, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
|
|
@ -1167,22 +1203,69 @@ void FurnaceGUI::initSystemPresets() {
|
|||
CH(DIV_SYSTEM_PCSPKR, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Sega TeraDrive", {
|
||||
CH(DIV_SYSTEM_YM2612, 1.0f, 0, ""),
|
||||
CH(DIV_SYSTEM_SMS, 0.5f, 0, ""),
|
||||
CH(DIV_SYSTEM_PCSPKR, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
SUB_SUB_ENTRY(
|
||||
"Sega TeraDrive (extended channel 3)", {
|
||||
CH(DIV_SYSTEM_YM2612_EXT, 1.0f, 0, ""),
|
||||
CH(DIV_SYSTEM_SMS, 0.5f, 0, ""),
|
||||
CH(DIV_SYSTEM_PCSPKR, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
SUB_SUB_ENTRY(
|
||||
"Sega TeraDrive (CSM)", {
|
||||
CH(DIV_SYSTEM_YM2612_CSM, 1.0f, 0, ""),
|
||||
CH(DIV_SYSTEM_SMS, 0.5f, 0, ""),
|
||||
CH(DIV_SYSTEM_PCSPKR, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
SUB_SUB_ENTRY(
|
||||
"Sega TeraDrive (DualPCM)", {
|
||||
CH(DIV_SYSTEM_YM2612_DUALPCM, 1.0f, 0, ""),
|
||||
CH(DIV_SYSTEM_SMS, 0.5f, 0, ""),
|
||||
CH(DIV_SYSTEM_PCSPKR, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
SUB_SUB_ENTRY(
|
||||
"Sega TeraDrive (DualPCM, extended channel 3)", {
|
||||
CH(DIV_SYSTEM_YM2612_DUALPCM_EXT, 1.0f, 0, ""),
|
||||
CH(DIV_SYSTEM_SMS, 0.5f, 0, ""),
|
||||
CH(DIV_SYSTEM_PCSPKR, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"Sharp X1", {
|
||||
CH(DIV_SYSTEM_AY8910, 1.0f, 0, "clockSel=3")
|
||||
}
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Sharp X1 + FM Addon", {
|
||||
CH(DIV_SYSTEM_AY8910, 1.0f, 0, "clockSel=3"),
|
||||
CH(DIV_SYSTEM_YM2151, 1.0f, 0, "clockSel=2")
|
||||
}
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"Sharp X68000", {
|
||||
CH(DIV_SYSTEM_YM2151, 1.0f, 0, "clockSel=2"),
|
||||
CH(DIV_SYSTEM_MSM6258, 1.0f, 0, "clockSel=2")
|
||||
}
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"FM-7", {
|
||||
CH(DIV_SYSTEM_AY8910, 1.0f, 0, "clockSel=12"),
|
||||
CH(DIV_SYSTEM_YM2203, 1.0f, 0, "clockSel=5")
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"FM-7 (extended channel 3)", {
|
||||
CH(DIV_SYSTEM_AY8910, 1.0f, 0, "clockSel=12"),
|
||||
CH(DIV_SYSTEM_YM2203_EXT, 1.0f, 0, "clockSel=5")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"FM Towns", {
|
||||
|
|
@ -1228,6 +1311,14 @@ void FurnaceGUI::initSystemPresets() {
|
|||
)
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"Sord M5", {
|
||||
CH(DIV_SYSTEM_SMS, 1.0f, 0,
|
||||
"customClock=1773447\n"
|
||||
"chipType=1\n"
|
||||
)
|
||||
}
|
||||
);
|
||||
CATEGORY_END;
|
||||
|
||||
CATEGORY_BEGIN("Arcade systems","INSERT COIN");
|
||||
|
|
@ -1236,7 +1327,7 @@ void FurnaceGUI::initSystemPresets() {
|
|||
"Alpha Denshi", {}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Alpha denshi Alpha-68K", {
|
||||
"Alpha Denshi Alpha-68K", {
|
||||
CH(DIV_SYSTEM_YM2203, 1.0f, 0, "clockSel=3"), // 3MHz
|
||||
CH(DIV_SYSTEM_OPLL, 1.0f, 0, "clockSel=0"), // 3.58MHz
|
||||
CH(DIV_SYSTEM_PCM_DAC, 1.0f, 0,
|
||||
|
|
@ -1246,7 +1337,7 @@ void FurnaceGUI::initSystemPresets() {
|
|||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Alpha denshi Alpha-68K (extended channel 3)", {
|
||||
"Alpha Denshi Alpha-68K (extended channel 3)", {
|
||||
CH(DIV_SYSTEM_YM2203_EXT, 1.0f, 0, "clockSel=3"), // 3MHz
|
||||
CH(DIV_SYSTEM_OPLL, 1.0f, 0, "clockSel=0"), // 3.58MHz
|
||||
CH(DIV_SYSTEM_PCM_DAC, 1.0f, 0,
|
||||
|
|
@ -1256,7 +1347,7 @@ void FurnaceGUI::initSystemPresets() {
|
|||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Alpha denshi Alpha-68K (drums mode)", {
|
||||
"Alpha Denshi Alpha-68K (drums mode)", {
|
||||
CH(DIV_SYSTEM_YM2203, 1.0f, 0, "clockSel=3"), // 3MHz
|
||||
CH(DIV_SYSTEM_OPLL_DRUMS, 1.0f, 0, "clockSel=0"), // 3.58MHz
|
||||
CH(DIV_SYSTEM_PCM_DAC, 1.0f, 0,
|
||||
|
|
@ -1266,7 +1357,7 @@ void FurnaceGUI::initSystemPresets() {
|
|||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Alpha denshi Alpha-68K (extended channel 3; drums mode)", {
|
||||
"Alpha Denshi Alpha-68K (extended channel 3; drums mode)", {
|
||||
CH(DIV_SYSTEM_YM2203_EXT, 1.0f, 0, "clockSel=3"), // 3MHz
|
||||
CH(DIV_SYSTEM_OPLL_DRUMS, 1.0f, 0, "clockSel=0"), // 3.58MHz
|
||||
CH(DIV_SYSTEM_PCM_DAC, 1.0f, 0,
|
||||
|
|
@ -1276,7 +1367,7 @@ void FurnaceGUI::initSystemPresets() {
|
|||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Alpha denshi Equites", {
|
||||
"Alpha Denshi Equites", {
|
||||
CH(DIV_SYSTEM_MSM5232, 1.0f, 0, "customClock=6144000"),
|
||||
CH(DIV_SYSTEM_AY8910, 1.0f, 0, "clockSel=14"),
|
||||
CH(DIV_SYSTEM_PCM_DAC, 1.0f, 0,
|
||||
|
|
@ -1354,7 +1445,7 @@ void FurnaceGUI::initSystemPresets() {
|
|||
"Capcom", {}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Capcom Exed Eyes", {
|
||||
"Capcom Exed Exes", {
|
||||
CH(DIV_SYSTEM_AY8910, 1.0f, 0, "clockSel=4"), // 1.5MHz
|
||||
CH(DIV_SYSTEM_SMS, 1.0f, 0,
|
||||
"clockSel=4\n"
|
||||
|
|
@ -1430,28 +1521,28 @@ void FurnaceGUI::initSystemPresets() {
|
|||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Data East Arcade", { // Bad dudes, Robocop, etc
|
||||
"Data East Arcade", { // Bad Dudes, RoboCop, etc
|
||||
CH(DIV_SYSTEM_YM2203, 1.0f, 0, "clockSel=5"), // 1.5MHz
|
||||
CH(DIV_SYSTEM_OPL2, 1.0f, 0, "clockSel=3"), // 3MHz
|
||||
CH(DIV_SYSTEM_MSM6295, 1.0f, 0, "") // 1 to 1.056MHz; various per games or optional
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Data East Arcade (extended channel 3)", { // Bad dudes, Robocop, etc
|
||||
"Data East Arcade (extended channel 3)", { // Bad Dudes, RoboCop, etc
|
||||
CH(DIV_SYSTEM_YM2203_EXT, 1.0f, 0, "clockSel=5"), // 1.5MHz
|
||||
CH(DIV_SYSTEM_OPL2, 1.0f, 0, "clockSel=3"), // 3MHz
|
||||
CH(DIV_SYSTEM_MSM6295, 1.0f, 0, "") // 1 to 1.056MHz; various per games or optional
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Data East Arcade (drums mode)", { // Bad dudes, Robocop, etc
|
||||
"Data East Arcade (drums mode)", { // Bad Dudes, RoboCop, etc
|
||||
CH(DIV_SYSTEM_YM2203, 1.0f, 0, "clockSel=5"), // 1.5MHz
|
||||
CH(DIV_SYSTEM_OPL2_DRUMS, 1.0f, 0, "clockSel=3"), // 3MHz
|
||||
CH(DIV_SYSTEM_MSM6295, 1.0f, 0, "") // 1 to 1.056MHz; various per games or optional
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Data East Arcade (extended channel 3; drums mode)", { // Bad dudes, Robocop, etc
|
||||
"Data East Arcade (extended channel 3; drums mode)", { // Bad Dudes, RoboCop, etc
|
||||
CH(DIV_SYSTEM_YM2203_EXT, 1.0f, 0, "clockSel=5"), // 1.5MHz
|
||||
CH(DIV_SYSTEM_OPL2_DRUMS, 1.0f, 0, "clockSel=3"), // 3MHz
|
||||
CH(DIV_SYSTEM_MSM6295, 1.0f, 0, "") // 1 to 1.056MHz; various per games or optional
|
||||
|
|
@ -1477,7 +1568,7 @@ void FurnaceGUI::initSystemPresets() {
|
|||
CH(DIV_SYSTEM_YM2203, 1.0f, 0, "clockSel=2"), // 4.0275MHz (32.22MHz / 8); optional
|
||||
CH(DIV_SYSTEM_MSM6295, 1.0f, 0, ""), // 1.007MHz (32.22MHz / 32)
|
||||
CH(DIV_SYSTEM_MSM6295, 1.0f, 0, "clockSel=8") // 2.014MHz (32.22MHz / 16); optional
|
||||
// HuC6280 is for control them, internal sound isn't used
|
||||
// HuC6280 is for controlling them; internal sound isn't used
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
|
|
@ -1486,7 +1577,7 @@ void FurnaceGUI::initSystemPresets() {
|
|||
CH(DIV_SYSTEM_YM2203_EXT, 1.0f, 0, "clockSel=2"), // 4.0275MHz (32.22MHz / 8); optional
|
||||
CH(DIV_SYSTEM_MSM6295, 1.0f, 0, ""), // 1.007MHz (32.22MHz / 32)
|
||||
CH(DIV_SYSTEM_MSM6295, 1.0f, 0, "clockSel=8") // 2.014MHz (32.22MHz / 16); optional
|
||||
// HuC6280 is for control them, internal sound isn't used
|
||||
// HuC6280 is for controlling them; internal sound isn't used
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
|
|
@ -2207,13 +2298,13 @@ void FurnaceGUI::initSystemPresets() {
|
|||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Seibu Kaihatsu Raiden", { // Raiden, Seibu cup soccer, Zero team, etc
|
||||
"Seibu Kaihatsu Raiden", { // Raiden, Seibu Cup Soccer, Zero Team, etc
|
||||
CH(DIV_SYSTEM_OPL2, 1.0f, 0, ""), // YM3812 3.58MHz
|
||||
CH(DIV_SYSTEM_MSM6295, 1.0f, 0, "") // 1 or 1.023MHz (28.636363MHz / 28); various per games
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Seibu Kaihatsu Raiden (drums mode)", { // Raiden, Seibu cup soccer, Zero team, etc
|
||||
"Seibu Kaihatsu Raiden (drums mode)", { // Raiden, Seibu Cup Soccer, Zero Team, etc
|
||||
CH(DIV_SYSTEM_OPL2_DRUMS, 1.0f, 0, ""), // YM3812 3.58MHz
|
||||
CH(DIV_SYSTEM_MSM6295, 1.0f, 0, "") // 1 or 1.023MHz (28.636363MHz / 28); various per games
|
||||
}
|
||||
|
|
@ -2835,7 +2926,7 @@ void FurnaceGUI::initSystemPresets() {
|
|||
}
|
||||
);
|
||||
ENTRY(
|
||||
"NDS", {
|
||||
"Nintendo DS", {
|
||||
CH(DIV_SYSTEM_NDS, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
|
|
@ -2961,6 +3052,11 @@ void FurnaceGUI::initSystemPresets() {
|
|||
CH(DIV_SYSTEM_TIA, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Atari TIA (with software pitch driver)", {
|
||||
CH(DIV_SYSTEM_TIA, 1.0f, 0, "softwarePitch=1")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"NES (Ricoh 2A03)", {
|
||||
CH(DIV_SYSTEM_NES, 1.0f, 0, "")
|
||||
|
|
@ -3014,6 +3110,16 @@ void FurnaceGUI::initSystemPresets() {
|
|||
CH(DIV_SYSTEM_NDS, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"Bifurcator", {
|
||||
CH(DIV_SYSTEM_BIFURCATOR, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"SID2", {
|
||||
CH(DIV_SYSTEM_SID2, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
CATEGORY_END;
|
||||
|
||||
CATEGORY_BEGIN("DefleMask-compatible","these configurations are compatible with DefleMask.\nselect this if you need to save as .dmf or work with that program.");
|
||||
|
|
@ -3098,11 +3204,9 @@ void FurnaceGUI::initSystemPresets() {
|
|||
CATEGORY_END;
|
||||
}
|
||||
|
||||
FurnaceGUISysDef::FurnaceGUISysDef(const char* n, std::initializer_list<FurnaceGUISysDefChip> def, const char* e):
|
||||
name(n),
|
||||
extra(e) {
|
||||
orig=def;
|
||||
void FurnaceGUISysDef::bake() {
|
||||
int index=0;
|
||||
definition="";
|
||||
for (FurnaceGUISysDefChip& i: orig) {
|
||||
definition+=fmt::sprintf(
|
||||
"id%d=%d\nvol%d=%f\npan%d=%f\nflags%d=%s\n",
|
||||
|
|
@ -3117,16 +3221,45 @@ FurnaceGUISysDef::FurnaceGUISysDef(const char* n, std::initializer_list<FurnaceG
|
|||
);
|
||||
index++;
|
||||
}
|
||||
if (extra) {
|
||||
if (!extra.empty()) {
|
||||
definition+=extra;
|
||||
}
|
||||
}
|
||||
|
||||
// functions for loading/saving user presets
|
||||
bool loadUserPresets(bool redundancy) {
|
||||
return true;
|
||||
FurnaceGUISysDef::FurnaceGUISysDef(const char* n, std::initializer_list<FurnaceGUISysDefChip> def, const char* e):
|
||||
name(n),
|
||||
extra((e==NULL)?"":e) {
|
||||
orig=def;
|
||||
bake();
|
||||
}
|
||||
|
||||
bool saveUserPresets(bool redundancy) {
|
||||
return true;
|
||||
}
|
||||
FurnaceGUISysDef::FurnaceGUISysDef(const char* n, const char* def, DivEngine* e):
|
||||
name(n),
|
||||
definition(taDecodeBase64(def)) {
|
||||
// extract definition
|
||||
DivConfig conf;
|
||||
conf.loadFromMemory(definition.c_str());
|
||||
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||
String nextStr=fmt::sprintf("id%d",i);
|
||||
int id=conf.getInt(nextStr.c_str(),0);
|
||||
if (id==0) break;
|
||||
conf.remove(nextStr.c_str());
|
||||
|
||||
nextStr=fmt::sprintf("vol%d",i);
|
||||
float vol=conf.getFloat(nextStr.c_str(),1.0f);
|
||||
conf.remove(nextStr.c_str());
|
||||
nextStr=fmt::sprintf("pan%d",i);
|
||||
float pan=conf.getFloat(nextStr.c_str(),0.0f);
|
||||
conf.remove(nextStr.c_str());
|
||||
nextStr=fmt::sprintf("fr%d",i);
|
||||
float panFR=conf.getFloat(nextStr.c_str(),0.0f);
|
||||
conf.remove(nextStr.c_str());
|
||||
nextStr=fmt::sprintf("flags%d",i);
|
||||
String flags=taDecodeBase64(conf.getString(nextStr.c_str(),"").c_str());
|
||||
conf.remove(nextStr.c_str());
|
||||
|
||||
orig.push_back(FurnaceGUISysDefChip(e->systemFromFileFur(id),vol,pan,flags.c_str(),panFR));
|
||||
}
|
||||
// extract extra
|
||||
extra=conf.toString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ void FurnaceGUI::drawRegView() {
|
|||
nextWindow=GUI_WINDOW_NOTHING;
|
||||
}
|
||||
if (!regViewOpen) return;
|
||||
if (ImGui::Begin("Register View",®ViewOpen,globalWinFlags)) {
|
||||
if (ImGui::Begin("Register View",®ViewOpen,globalWinFlags,_("Register View"))) {
|
||||
for (int i=0; i<e->song.systemLen; i++) {
|
||||
ImGui::Text("%d. %s",i+1,getSystemName(e->song.system[i]));
|
||||
int size=0;
|
||||
|
|
@ -35,7 +35,7 @@ void FurnaceGUI::drawRegView() {
|
|||
unsigned char* regPool=e->getRegisterPool(i,size,depth);
|
||||
unsigned short* regPoolW=(unsigned short*)regPool;
|
||||
if (regPool==NULL) {
|
||||
ImGui::Text("- no register pool available");
|
||||
ImGui::Text(_("- no register pool available"));
|
||||
} else {
|
||||
ImGui::PushFont(patFont);
|
||||
if (ImGui::BeginTable("Memory",17)) {
|
||||
|
|
|
|||
|
|
@ -25,30 +25,73 @@
|
|||
#ifdef HAVE_RENDER_GL
|
||||
#include "render/renderGL.h"
|
||||
#endif
|
||||
#ifdef HAVE_RENDER_GL1
|
||||
#include "render/renderGL1.h"
|
||||
#endif
|
||||
#ifdef HAVE_RENDER_DX11
|
||||
#include "render/renderDX11.h"
|
||||
#endif
|
||||
#ifdef HAVE_RENDER_DX9
|
||||
#include "render/renderDX9.h"
|
||||
#endif
|
||||
#ifdef HAVE_RENDER_METAL
|
||||
#include "render/renderMetal.h"
|
||||
#endif
|
||||
#include "render/renderSoftware.h"
|
||||
|
||||
bool FurnaceGUI::initRender() {
|
||||
if (rend!=NULL) return false;
|
||||
|
||||
logV("requested backend: %s",settings.renderBackend);
|
||||
|
||||
if (safeMode) {
|
||||
renderBackend=GUI_BACKEND_SDL;
|
||||
} else if (settings.renderBackend=="OpenGL") {
|
||||
renderBackend=GUI_BACKEND_GL;
|
||||
renderBackend=GUI_BACKEND_SOFTWARE;
|
||||
} else if (settings.renderBackend=="OpenGL" || settings.renderBackend=="OpenGL 3.0" || settings.renderBackend=="OpenGL ES 2.0") {
|
||||
renderBackend=GUI_BACKEND_GL3;
|
||||
} else if (settings.renderBackend=="OpenGL 2.0") {
|
||||
renderBackend=GUI_BACKEND_GL2;
|
||||
} else if (settings.renderBackend=="OpenGL 1.1") {
|
||||
renderBackend=GUI_BACKEND_GL1;
|
||||
} else if (settings.renderBackend=="DirectX 11") {
|
||||
renderBackend=GUI_BACKEND_DX11;
|
||||
} else if (settings.renderBackend=="DirectX 9") {
|
||||
renderBackend=GUI_BACKEND_DX9;
|
||||
} else if (settings.renderBackend=="Metal") {
|
||||
renderBackend=GUI_BACKEND_METAL;
|
||||
} else if (settings.renderBackend=="SDL") {
|
||||
renderBackend=GUI_BACKEND_SDL;
|
||||
} else if (settings.renderBackend=="Software") {
|
||||
renderBackend=GUI_BACKEND_SOFTWARE;
|
||||
} else {
|
||||
renderBackend=GUI_BACKEND_DEFAULT;
|
||||
}
|
||||
|
||||
switch (renderBackend) {
|
||||
#ifdef HAVE_RENDER_GL
|
||||
case GUI_BACKEND_GL:
|
||||
logI("render backend: OpenGL");
|
||||
#ifdef USE_GLES
|
||||
case GUI_BACKEND_GL3:
|
||||
case GUI_BACKEND_GL2:
|
||||
logI("render backend: OpenGL ES 2.0");
|
||||
rend=new FurnaceGUIRenderGL;
|
||||
((FurnaceGUIRenderGL*)rend)->setVersion(3);
|
||||
break;
|
||||
#else
|
||||
case GUI_BACKEND_GL3:
|
||||
logI("render backend: OpenGL 3.0");
|
||||
rend=new FurnaceGUIRenderGL;
|
||||
((FurnaceGUIRenderGL*)rend)->setVersion(3);
|
||||
break;
|
||||
case GUI_BACKEND_GL2:
|
||||
logI("render backend: OpenGL 2.0");
|
||||
rend=new FurnaceGUIRenderGL;
|
||||
((FurnaceGUIRenderGL*)rend)->setVersion(2);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_RENDER_GL1
|
||||
case GUI_BACKEND_GL1:
|
||||
logI("render backend: OpenGL 1.1");
|
||||
rend=new FurnaceGUIRenderGL1;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_RENDER_DX11
|
||||
|
|
@ -57,12 +100,28 @@ bool FurnaceGUI::initRender() {
|
|||
rend=new FurnaceGUIRenderDX11;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_RENDER_DX9
|
||||
case GUI_BACKEND_DX9:
|
||||
logI("render backend: DirectX 9");
|
||||
rend=new FurnaceGUIRenderDX9;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_RENDER_METAL
|
||||
case GUI_BACKEND_METAL:
|
||||
logI("render backend: Metal");
|
||||
rend=new FurnaceGUIRenderMetal;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_RENDER_SDL
|
||||
case GUI_BACKEND_SDL:
|
||||
logI("render backend: SDL_Renderer");
|
||||
rend=new FurnaceGUIRenderSDL;
|
||||
break;
|
||||
#endif
|
||||
case GUI_BACKEND_SOFTWARE:
|
||||
logI("render backend: Software");
|
||||
rend=new FurnaceGUIRenderSoftware;
|
||||
break;
|
||||
default:
|
||||
logE("invalid render backend!");
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,22 @@ ImTextureID FurnaceGUIRender::getTextureID(FurnaceGUITexture* which) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
float FurnaceGUIRender::getTextureU(FurnaceGUITexture* which) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
float FurnaceGUIRender::getTextureV(FurnaceGUITexture* which) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
FurnaceGUITextureFormat FurnaceGUIRender::getTextureFormat(FurnaceGUITexture* which) {
|
||||
return GUI_TEXFORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRender::isTextureValid(FurnaceGUITexture* which) {
|
||||
return (which!=NULL);
|
||||
}
|
||||
|
||||
bool FurnaceGUIRender::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -35,7 +51,7 @@ bool FurnaceGUIRender::updateTexture(FurnaceGUITexture* which, void* data, int p
|
|||
return false;
|
||||
}
|
||||
|
||||
FurnaceGUITexture* FurnaceGUIRender::createTexture(bool dynamic, int width, int height) {
|
||||
FurnaceGUITexture* FurnaceGUIRender::createTexture(bool dynamic, int width, int height, bool interpolate, FurnaceGUITextureFormat format) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -59,6 +75,10 @@ bool FurnaceGUIRender::newFrame() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRender::canVSync() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void FurnaceGUIRender::createFontsTexture() {
|
||||
}
|
||||
|
||||
|
|
@ -85,14 +105,49 @@ bool FurnaceGUIRender::supportsDrawOsc() {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRender::areTexturesSquare() {
|
||||
return false;
|
||||
}
|
||||
|
||||
int FurnaceGUIRender::getWindowFlags() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FurnaceGUIRender::preInit() {
|
||||
int FurnaceGUIRender::getMaxTextureWidth() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRender::init(SDL_Window* win) {
|
||||
int FurnaceGUIRender::getMaxTextureHeight() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int FurnaceGUIRender::getTextureFormats() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRender::getBackendName() {
|
||||
return "Dummy";
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRender::getVendorName() {
|
||||
return "N/A";
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRender::getDeviceName() {
|
||||
return "N/A";
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRender::getAPIVersion() {
|
||||
return "N/A";
|
||||
}
|
||||
|
||||
void FurnaceGUIRender::setSwapInterval(int swapInterval) {
|
||||
}
|
||||
|
||||
void FurnaceGUIRender::preInit(const DivConfig& conf) {
|
||||
}
|
||||
|
||||
bool FurnaceGUIRender::init(SDL_Window* win, int swapInterval) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -110,13 +165,5 @@ bool FurnaceGUIRender::isDead() {
|
|||
return false;
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRender::getStupidFragment() {
|
||||
return "Only OpenGL";
|
||||
}
|
||||
|
||||
bool FurnaceGUIRender::regenOscShader(const char* fragment) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FurnaceGUIRender::~FurnaceGUIRender() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <SDL_syswm.h>
|
||||
#include "backends/imgui_impl_dx11.h"
|
||||
#include "../../ta-log.h"
|
||||
#include "../../utfutils.h"
|
||||
|
||||
typedef HRESULT (__stdcall *D3DCompile_t)(LPCVOID,SIZE_T,LPCSTR,D3D_SHADER_MACRO*,ID3DInclude*,LPCSTR,LPCSTR,UINT,UINT,ID3DBlob**,ID3DBlob*);
|
||||
|
||||
|
|
@ -74,6 +75,7 @@ class FurnaceDXTexture: public FurnaceGUITexture {
|
|||
ID3D11Texture2D* tex;
|
||||
ID3D11ShaderResourceView* view;
|
||||
int width, height;
|
||||
FurnaceGUITextureFormat format;
|
||||
unsigned char* lockedData;
|
||||
bool dynamic;
|
||||
FurnaceDXTexture():
|
||||
|
|
@ -81,6 +83,7 @@ class FurnaceDXTexture: public FurnaceGUITexture {
|
|||
view(NULL),
|
||||
width(0),
|
||||
height(0),
|
||||
format(GUI_TEXFORMAT_UNKNOWN),
|
||||
lockedData(NULL),
|
||||
dynamic(false) {}
|
||||
};
|
||||
|
|
@ -146,6 +149,11 @@ ImTextureID FurnaceGUIRenderDX11::getTextureID(FurnaceGUITexture* which) {
|
|||
return (ImTextureID)t->view;
|
||||
}
|
||||
|
||||
FurnaceGUITextureFormat FurnaceGUIRenderDX11::getTextureFormat(FurnaceGUITexture* which) {
|
||||
FurnaceDXTexture* t=(FurnaceDXTexture*)which;
|
||||
return t->format;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderDX11::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) {
|
||||
FurnaceDXTexture* t=(FurnaceDXTexture*)which;
|
||||
if (t->lockedData!=NULL) return false;
|
||||
|
|
@ -199,7 +207,7 @@ bool FurnaceGUIRenderDX11::updateTexture(FurnaceGUITexture* which, void* data, i
|
|||
return true;
|
||||
}
|
||||
|
||||
FurnaceGUITexture* FurnaceGUIRenderDX11::createTexture(bool dynamic, int width, int height) {
|
||||
FurnaceGUITexture* FurnaceGUIRenderDX11::createTexture(bool dynamic, int width, int height, bool interpolate, FurnaceGUITextureFormat format) {
|
||||
D3D11_TEXTURE2D_DESC texDesc;
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
|
||||
ID3D11Texture2D* tex=NULL;
|
||||
|
|
@ -213,7 +221,17 @@ FurnaceGUITexture* FurnaceGUIRenderDX11::createTexture(bool dynamic, int width,
|
|||
texDesc.Height=height;
|
||||
texDesc.MipLevels=1;
|
||||
texDesc.ArraySize=1;
|
||||
texDesc.Format=DXGI_FORMAT_R8G8B8A8_UNORM; // ???
|
||||
switch (format) {
|
||||
case GUI_TEXFORMAT_ABGR32:
|
||||
texDesc.Format=DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
break;
|
||||
case GUI_TEXFORMAT_ARGB32:
|
||||
texDesc.Format=DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
break;
|
||||
default:
|
||||
logE("unsupported texture format!");
|
||||
return NULL;
|
||||
}
|
||||
texDesc.SampleDesc.Count=1;
|
||||
texDesc.SampleDesc.Quality=0;
|
||||
texDesc.Usage=dynamic?D3D11_USAGE_DYNAMIC:D3D11_USAGE_DEFAULT;
|
||||
|
|
@ -245,6 +263,7 @@ FurnaceGUITexture* FurnaceGUIRenderDX11::createTexture(bool dynamic, int width,
|
|||
ret->tex=tex;
|
||||
ret->view=view;
|
||||
ret->dynamic=dynamic;
|
||||
ret->format=format;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -293,6 +312,11 @@ bool FurnaceGUIRenderDX11::newFrame() {
|
|||
return ImGui_ImplDX11_NewFrame();
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderDX11::canVSync() {
|
||||
// TODO: find out how to retrieve VSync status
|
||||
return true;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX11::createFontsTexture() {
|
||||
ImGui_ImplDX11_CreateDeviceObjects();
|
||||
}
|
||||
|
|
@ -345,7 +369,7 @@ void FurnaceGUIRenderDX11::wipe(float alpha) {
|
|||
}
|
||||
|
||||
void FurnaceGUIRenderDX11::present() {
|
||||
HRESULT result=swapchain->Present(1,0);
|
||||
HRESULT result=swapchain->Present(swapInterval,0);
|
||||
if (result==DXGI_ERROR_DEVICE_REMOVED || result==DXGI_ERROR_DEVICE_RESET) {
|
||||
dead=true;
|
||||
} else if (result!=S_OK && result!=DXGI_STATUS_OCCLUDED) {
|
||||
|
|
@ -363,7 +387,39 @@ int FurnaceGUIRenderDX11::getWindowFlags() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX11::preInit() {
|
||||
int FurnaceGUIRenderDX11::getMaxTextureWidth() {
|
||||
return maxWidth;
|
||||
}
|
||||
|
||||
int FurnaceGUIRenderDX11::getMaxTextureHeight() {
|
||||
return maxHeight;
|
||||
}
|
||||
|
||||
unsigned int FurnaceGUIRenderDX11::getTextureFormats() {
|
||||
return GUI_TEXFORMAT_ABGR32|GUI_TEXFORMAT_ARGB32;
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderDX11::getBackendName() {
|
||||
return "DirectX 11";
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderDX11::getVendorName() {
|
||||
return vendorName.c_str();
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderDX11::getDeviceName() {
|
||||
return deviceName.c_str();
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderDX11::getAPIVersion() {
|
||||
return apiVersion.c_str();
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX11::setSwapInterval(int swapInt) {
|
||||
swapInterval=swapInt;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX11::preInit(const DivConfig& conf) {
|
||||
}
|
||||
|
||||
const float wipeVertices[4][4]={
|
||||
|
|
@ -373,7 +429,7 @@ const float wipeVertices[4][4]={
|
|||
{ 1.0, 1.0, 0.0, 1.0}
|
||||
};
|
||||
|
||||
bool FurnaceGUIRenderDX11::init(SDL_Window* win) {
|
||||
bool FurnaceGUIRenderDX11::init(SDL_Window* win, int swapInt) {
|
||||
SDL_SysWMinfo sysWindow;
|
||||
D3D_FEATURE_LEVEL featureLevel;
|
||||
|
||||
|
|
@ -384,6 +440,9 @@ bool FurnaceGUIRenderDX11::init(SDL_Window* win) {
|
|||
}
|
||||
HWND window=(HWND)sysWindow.info.win.window;
|
||||
|
||||
// prepare swapchain
|
||||
swapInterval=swapInt;
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC chainDesc;
|
||||
memset(&chainDesc,0,sizeof(chainDesc));
|
||||
chainDesc.BufferDesc.Width=0;
|
||||
|
|
@ -400,12 +459,51 @@ bool FurnaceGUIRenderDX11::init(SDL_Window* win) {
|
|||
chainDesc.SwapEffect=DXGI_SWAP_EFFECT_DISCARD;
|
||||
chainDesc.Flags=DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
|
||||
// initialize
|
||||
HRESULT result=D3D11CreateDeviceAndSwapChain(NULL,D3D_DRIVER_TYPE_HARDWARE,NULL,0,possibleFeatureLevels,2,D3D11_SDK_VERSION,&chainDesc,&swapchain,&device,&featureLevel,&context);
|
||||
if (result!=S_OK) {
|
||||
logE("could not create device and/or swap chain! %.8x",result);
|
||||
return false;
|
||||
}
|
||||
|
||||
IDXGIDevice* giDevice=NULL;
|
||||
IDXGIAdapter* adapter=NULL;
|
||||
|
||||
result=device->QueryInterface(__uuidof(IDXGIDevice),(void**)&giDevice);
|
||||
if (result==S_OK) {
|
||||
result=giDevice->GetAdapter(&adapter);
|
||||
if (result==S_OK) {
|
||||
DXGI_ADAPTER_DESC adapterDesc;
|
||||
|
||||
result=adapter->GetDesc(&adapterDesc);
|
||||
if (result!=S_OK) {
|
||||
logE("could not get adapter info! %.8x",result);
|
||||
} else {
|
||||
deviceName=utf16To8(adapterDesc.Description);
|
||||
vendorName=fmt::sprintf("%.4x:%.4x",adapterDesc.VendorId,adapterDesc.DeviceId);
|
||||
logV("device: %s",deviceName);
|
||||
}
|
||||
} else {
|
||||
logE("could not get adapter! %.8x",result);
|
||||
logE("won't be able to get adapter info...");
|
||||
}
|
||||
} else {
|
||||
logE("could not query interface! %.8x",result);
|
||||
logE("won't be able to get adapter info...");
|
||||
}
|
||||
|
||||
if (featureLevel>=0xb000) {
|
||||
maxWidth=16384;
|
||||
maxHeight=16384;
|
||||
} else if (featureLevel>=0xa000) {
|
||||
maxWidth=8192;
|
||||
maxHeight=8192;
|
||||
} else {
|
||||
maxWidth=4096;
|
||||
maxHeight=4096;
|
||||
}
|
||||
apiVersion=fmt::sprintf("%d.%d",((int)featureLevel)>>12,((int)featureLevel)>>8);
|
||||
|
||||
// https://github.com/ocornut/imgui/pull/638
|
||||
D3DCompile_t D3DCompile=NULL;
|
||||
char dllBuffer[20];
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender {
|
|||
ID3D11BlendState* omBlendState;
|
||||
|
||||
ID3D11Buffer* quadVertex;
|
||||
int outW, outH;
|
||||
int outW, outH, swapInterval;
|
||||
|
||||
bool dead;
|
||||
|
||||
|
|
@ -56,21 +56,26 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender {
|
|||
float padding[7];
|
||||
};
|
||||
|
||||
int maxWidth, maxHeight;
|
||||
String vendorName, deviceName, apiVersion;
|
||||
|
||||
bool destroyRenderTarget();
|
||||
bool createRenderTarget();
|
||||
|
||||
public:
|
||||
ImTextureID getTextureID(FurnaceGUITexture* which);
|
||||
FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which);
|
||||
bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
|
||||
bool unlockTexture(FurnaceGUITexture* which);
|
||||
bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
|
||||
FurnaceGUITexture* createTexture(bool dynamic, int width, int height);
|
||||
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true, FurnaceGUITextureFormat format=GUI_TEXFORMAT_ABGR32);
|
||||
bool destroyTexture(FurnaceGUITexture* which);
|
||||
void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
|
||||
void setBlendMode(FurnaceGUIBlendMode mode);
|
||||
void resized(const SDL_Event& ev);
|
||||
void clear(ImVec4 color);
|
||||
bool newFrame();
|
||||
bool canVSync();
|
||||
void createFontsTexture();
|
||||
void destroyFontsTexture();
|
||||
void renderGUI();
|
||||
|
|
@ -78,8 +83,16 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender {
|
|||
void present();
|
||||
bool getOutputSize(int& w, int& h);
|
||||
int getWindowFlags();
|
||||
void preInit();
|
||||
bool init(SDL_Window* win);
|
||||
int getMaxTextureWidth();
|
||||
int getMaxTextureHeight();
|
||||
unsigned int getTextureFormats();
|
||||
const char* getBackendName();
|
||||
const char* getVendorName();
|
||||
const char* getDeviceName();
|
||||
const char* getAPIVersion();
|
||||
void setSwapInterval(int swapInterval);
|
||||
void preInit(const DivConfig& conf);
|
||||
bool init(SDL_Window* win, int swapInterval);
|
||||
void initGUI(SDL_Window* win);
|
||||
void quitGUI();
|
||||
bool quit();
|
||||
|
|
@ -94,10 +107,13 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender {
|
|||
quadVertex(NULL),
|
||||
outW(0),
|
||||
outH(0),
|
||||
swapInterval(1),
|
||||
dead(false),
|
||||
sh_wipe_vertex(NULL),
|
||||
sh_wipe_fragment(NULL),
|
||||
sh_wipe_inputLayout(NULL),
|
||||
sh_wipe_uniform(NULL) {
|
||||
sh_wipe_uniform(NULL),
|
||||
maxWidth(8192),
|
||||
maxHeight(8192) {
|
||||
}
|
||||
};
|
||||
|
|
|
|||
597
src/gui/render/renderDX9.cpp
Normal file
597
src/gui/render/renderDX9.cpp
Normal file
|
|
@ -0,0 +1,597 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2024 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.
|
||||
*/
|
||||
|
||||
#define INCLUDE_D3D9
|
||||
#include "renderDX9.h"
|
||||
#include <SDL_syswm.h>
|
||||
#include "backends/imgui_impl_dx9.h"
|
||||
#include "../../ta-log.h"
|
||||
#include "../../utfutils.h"
|
||||
#include "../engine/bsr.h"
|
||||
|
||||
class FurnaceDX9Texture: public FurnaceGUITexture {
|
||||
public:
|
||||
IDirect3DTexture9* tex;
|
||||
IDirect3DTexture9* texPre;
|
||||
int width, height, widthReal, heightReal;
|
||||
FurnaceGUITextureFormat format;
|
||||
unsigned char* lockedData;
|
||||
bool dynamic;
|
||||
FurnaceDX9Texture():
|
||||
tex(NULL),
|
||||
texPre(NULL),
|
||||
width(0),
|
||||
height(0),
|
||||
widthReal(0),
|
||||
heightReal(0),
|
||||
format(GUI_TEXFORMAT_UNKNOWN),
|
||||
lockedData(NULL),
|
||||
dynamic(false) {}
|
||||
};
|
||||
|
||||
struct FurnaceGUIRenderDX9Private {
|
||||
D3DPRESENT_PARAMETERS present;
|
||||
std::vector<FurnaceDX9Texture*> texPool;
|
||||
};
|
||||
|
||||
struct WipeVertex {
|
||||
float x, y, z;
|
||||
unsigned int color;
|
||||
|
||||
WipeVertex(float _x, float _y, float _z, unsigned int c):
|
||||
x(_x),
|
||||
y(_y),
|
||||
z(_z),
|
||||
color(c) {}
|
||||
WipeVertex():
|
||||
x(0),
|
||||
y(0),
|
||||
z(0),
|
||||
color(0) {}
|
||||
};
|
||||
|
||||
|
||||
ImTextureID FurnaceGUIRenderDX9::getTextureID(FurnaceGUITexture* which) {
|
||||
FurnaceDX9Texture* t=(FurnaceDX9Texture*)which;
|
||||
return (ImTextureID)t->tex;
|
||||
}
|
||||
|
||||
float FurnaceGUIRenderDX9::getTextureU(FurnaceGUITexture* which) {
|
||||
FurnaceDX9Texture* t=(FurnaceDX9Texture*)which;
|
||||
if (which==NULL) return 0.0;
|
||||
if (t->widthReal<1) return 0.0f;
|
||||
return (float)t->width/(float)t->widthReal;
|
||||
}
|
||||
|
||||
float FurnaceGUIRenderDX9::getTextureV(FurnaceGUITexture* which) {
|
||||
FurnaceDX9Texture* t=(FurnaceDX9Texture*)which;
|
||||
if (which==NULL) return 0.0;
|
||||
if (t->heightReal<1) return 0.0f;
|
||||
return (float)t->height/(float)t->heightReal;
|
||||
}
|
||||
|
||||
FurnaceGUITextureFormat FurnaceGUIRenderDX9::getTextureFormat(FurnaceGUITexture* which) {
|
||||
FurnaceDX9Texture* t=(FurnaceDX9Texture*)which;
|
||||
return t->format;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderDX9::isTextureValid(FurnaceGUITexture* which) {
|
||||
if (which==NULL) return false;
|
||||
FurnaceDX9Texture* t=(FurnaceDX9Texture*)which;
|
||||
return (t->tex!=NULL);
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderDX9::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) {
|
||||
FurnaceDX9Texture* t=(FurnaceDX9Texture*)which;
|
||||
D3DLOCKED_RECT lockedRect;
|
||||
|
||||
HRESULT result=t->tex->LockRect(0,&lockedRect,NULL,D3DLOCK_DISCARD);
|
||||
|
||||
if (result!=D3D_OK) {
|
||||
logW("could not lock texture!");
|
||||
return false;
|
||||
}
|
||||
|
||||
*data=lockedRect.pBits;
|
||||
*pitch=lockedRect.Pitch;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderDX9::unlockTexture(FurnaceGUITexture* which) {
|
||||
FurnaceDX9Texture* t=(FurnaceDX9Texture*)which;
|
||||
HRESULT result=t->tex->UnlockRect(0);
|
||||
|
||||
if (result!=D3D_OK) {
|
||||
logW("could not unlock texture!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderDX9::updateTexture(FurnaceGUITexture* which, void* data, int pitch) {
|
||||
FurnaceDX9Texture* t=(FurnaceDX9Texture*)which;
|
||||
IDirect3DTexture9* crap=NULL;
|
||||
|
||||
if (t->texPre==NULL) {
|
||||
// update by locking
|
||||
if (!t->dynamic) {
|
||||
logW("updating static texture but texPre does not exist!");
|
||||
return false;
|
||||
}
|
||||
crap=t->tex;
|
||||
} else {
|
||||
// update by calling UpdateTexture
|
||||
crap=t->texPre;
|
||||
}
|
||||
|
||||
D3DLOCKED_RECT lockedRect;
|
||||
HRESULT result=crap->LockRect(0,&lockedRect,NULL,D3DLOCK_DISCARD);
|
||||
if (result!=D3D_OK) {
|
||||
logW("could not update texture (lock)! %.8x",result);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lockedRect.Pitch==pitch) {
|
||||
memcpy(lockedRect.pBits,data,pitch*t->height);
|
||||
} else {
|
||||
unsigned char* ucData=(unsigned char*)data;
|
||||
unsigned char* d=(unsigned char*)lockedRect.pBits;
|
||||
int srcPos=0;
|
||||
int destPos=0;
|
||||
for (int i=0; i<t->height; i++) {
|
||||
memcpy(&d[destPos],&ucData[srcPos],pitch);
|
||||
srcPos+=pitch;
|
||||
destPos+=lockedRect.Pitch;
|
||||
}
|
||||
}
|
||||
|
||||
crap->UnlockRect(0);
|
||||
|
||||
if (t->texPre!=NULL) {
|
||||
result=t->tex->AddDirtyRect(NULL);
|
||||
if (result!=D3D_OK) {
|
||||
logW("could not taint texture! %.8x",result);
|
||||
}
|
||||
result=device->UpdateTexture(t->texPre,t->tex);
|
||||
if (result!=D3D_OK) {
|
||||
logW("could not update texture! %.8x",result);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, int height, bool interpolate, FurnaceGUITextureFormat format) {
|
||||
IDirect3DTexture9* tex=NULL;
|
||||
IDirect3DTexture9* texPre=NULL;
|
||||
int widthReal=width;
|
||||
int heightReal=height;
|
||||
|
||||
if (format!=GUI_TEXFORMAT_ARGB32) {
|
||||
logE("unsupported texture format!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((widthReal&(widthReal-1))!=0) {
|
||||
widthReal=1<<bsr(width);
|
||||
}
|
||||
if ((heightReal&(heightReal-1))!=0) {
|
||||
heightReal=1<<bsr(height);
|
||||
}
|
||||
if (squareTex) {
|
||||
if (widthReal>heightReal) {
|
||||
heightReal=widthReal;
|
||||
} else {
|
||||
widthReal=heightReal;
|
||||
}
|
||||
}
|
||||
logV("width: %d (requested)... %d (actual)",width,widthReal);
|
||||
logV("height: %d (requested)... %d (actual)",height,heightReal);
|
||||
|
||||
if (!supportsDynamicTex) dynamic=false;
|
||||
|
||||
HRESULT result=device->CreateTexture(widthReal,heightReal,1,dynamic?D3DUSAGE_DYNAMIC:0,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&tex,NULL);
|
||||
|
||||
if (result!=D3D_OK) {
|
||||
logW("could not create texture! %.8x",result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dynamic) {
|
||||
HRESULT result=device->CreateTexture(widthReal,heightReal,1,0,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM,&texPre,NULL);
|
||||
|
||||
if (result!=D3D_OK) {
|
||||
logW("could not create pre-texture! %.8x",result);
|
||||
tex->Release();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
FurnaceDX9Texture* ret=new FurnaceDX9Texture;
|
||||
ret->width=width;
|
||||
ret->height=height;
|
||||
ret->widthReal=widthReal;
|
||||
ret->heightReal=heightReal;
|
||||
ret->tex=tex;
|
||||
ret->texPre=texPre;
|
||||
ret->dynamic=dynamic;
|
||||
ret->format=format;
|
||||
|
||||
priv->texPool.push_back(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderDX9::destroyTexture(FurnaceGUITexture* which) {
|
||||
FurnaceDX9Texture* t=(FurnaceDX9Texture*)which;
|
||||
if (t->texPre!=NULL) t->texPre->Release();
|
||||
if (t->tex!=NULL) t->tex->Release();
|
||||
delete t;
|
||||
|
||||
for (size_t i=0; i<priv->texPool.size(); i++) {
|
||||
if (priv->texPool[i]==t) {
|
||||
priv->texPool.erase(priv->texPool.begin()+i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX9::setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode) {
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX9::setBlendMode(FurnaceGUIBlendMode mode) {
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX9::resized(const SDL_Event& ev) {
|
||||
mustResize=true;
|
||||
outW=ev.window.data1;
|
||||
outH=ev.window.data2;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX9::clear(ImVec4 color) {
|
||||
device->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,ImGui::ColorConvertFloat4ToU32(color),0,0);
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX9::present() {
|
||||
if (inScene) {
|
||||
device->EndScene();
|
||||
inScene=false;
|
||||
}
|
||||
|
||||
if (device->Present(NULL,NULL,NULL,NULL)==D3DERR_DEVICEREMOVED) {
|
||||
logI("device is gone");
|
||||
dead=true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mustResize) {
|
||||
logI("DX9: resizing buffers");
|
||||
ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||
|
||||
if (wipeBuf) {
|
||||
wipeBuf->Release();
|
||||
wipeBuf=NULL;
|
||||
}
|
||||
|
||||
for (FurnaceDX9Texture* i: priv->texPool) {
|
||||
if (i->tex) {
|
||||
i->tex->Release();
|
||||
i->tex=NULL;
|
||||
}
|
||||
if (i->texPre) {
|
||||
i->texPre->Release();
|
||||
i->texPre=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
priv->present.BackBufferWidth=outW;
|
||||
priv->present.BackBufferHeight=outH;
|
||||
priv->present.BackBufferCount=1;
|
||||
HRESULT result=device->Reset(&priv->present);
|
||||
priv->present.BackBufferWidth=outW;
|
||||
priv->present.BackBufferHeight=outH;
|
||||
priv->present.BackBufferCount=1;
|
||||
if (result==D3DERR_INVALIDCALL) {
|
||||
logE("OH NO");
|
||||
dead=true;
|
||||
mustResize=false;
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui_ImplDX9_CreateDeviceObjects();
|
||||
|
||||
result=device->CreateVertexBuffer(sizeof(WipeVertex)*4,0,D3DFVF_XYZ|D3DFVF_DIFFUSE,D3DPOOL_DEFAULT,&wipeBuf,NULL);
|
||||
|
||||
if (result!=D3D_OK) {
|
||||
logE("could not create wipe buffer! %.8x",result);
|
||||
}
|
||||
|
||||
mustResize=false;
|
||||
}
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderDX9::newFrame() {
|
||||
return ImGui_ImplDX9_NewFrame();
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderDX9::canVSync() {
|
||||
return supportsVSync;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX9::createFontsTexture() {
|
||||
ImGui_ImplDX9_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX9::destroyFontsTexture() {
|
||||
ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX9::renderGUI() {
|
||||
if (!inScene) {
|
||||
HRESULT result=device->BeginScene();
|
||||
if (result!=D3D_OK) {
|
||||
logW("couldn't render GUI! %.8x",result);
|
||||
return;
|
||||
}
|
||||
inScene=true;
|
||||
}
|
||||
|
||||
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX9::wipe(float alpha) {
|
||||
if (wipeBuf==NULL) return;
|
||||
|
||||
logV("WIPE...");
|
||||
|
||||
if (!inScene) {
|
||||
HRESULT result=device->BeginScene();
|
||||
if (result!=D3D_OK) {
|
||||
logW("couldn't render GUI! %.8x",result);
|
||||
return;
|
||||
}
|
||||
inScene=true;
|
||||
}
|
||||
|
||||
D3DVIEWPORT9 view;
|
||||
view.X=0;
|
||||
view.Y=0;
|
||||
view.Width=outW;
|
||||
view.Height=outH;
|
||||
view.MinZ=0.0f;
|
||||
view.MaxZ=1.0f;
|
||||
HRESULT result=device->SetViewport(&view);
|
||||
if (result!=D3D_OK) {
|
||||
logW("could not set viewport! %.8x",result);
|
||||
}
|
||||
|
||||
unsigned char alphaU=alpha*255.0f;
|
||||
unsigned int color=alphaU<<24;
|
||||
|
||||
void* lockedData;
|
||||
WipeVertex vertex[4];
|
||||
vertex[0]=WipeVertex(0,0,0,color);
|
||||
vertex[1]=WipeVertex(outW,0,0,color);
|
||||
vertex[2]=WipeVertex(outW,outH,0,color);
|
||||
vertex[3]=WipeVertex(0,outH,0,color);
|
||||
|
||||
result=wipeBuf->Lock(0,0,&lockedData,D3DLOCK_DISCARD);
|
||||
if (result==D3D_OK) {
|
||||
memcpy(lockedData,vertex,sizeof(WipeVertex)*4);
|
||||
wipeBuf->Unlock();
|
||||
|
||||
result=device->SetRenderState(D3DRS_SCISSORTESTENABLE,FALSE);
|
||||
if (result!=D3D_OK) {
|
||||
logE("SHIT! scissor, %.8x",result);
|
||||
}
|
||||
result=device->SetTexture(0,NULL);
|
||||
if (result!=D3D_OK) {
|
||||
logE("SHIT! set texture, %.8x",result);
|
||||
}
|
||||
result=device->SetStreamSource(0,wipeBuf,0,sizeof(WipeVertex));
|
||||
if (result!=D3D_OK) {
|
||||
logE("SHIT! set stream source, %.8x",result);
|
||||
}
|
||||
result=device->SetTexture(0,NULL);
|
||||
if (result!=D3D_OK) {
|
||||
logE("SHIT! set texture, %.8x",result);
|
||||
}
|
||||
result=device->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE);
|
||||
if (result!=D3D_OK) {
|
||||
logE("SHIT! set FVF, %.8x",result);
|
||||
}
|
||||
result=device->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);
|
||||
if (result!=D3D_OK) {
|
||||
logE("SHIT! draw primitive, %.8x",result);
|
||||
}
|
||||
} else {
|
||||
logE("SHIT! lock, %.8x",result);
|
||||
}
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderDX9::getOutputSize(int& w, int& h) {
|
||||
w=outW;
|
||||
h=outH;
|
||||
return true;
|
||||
}
|
||||
|
||||
int FurnaceGUIRenderDX9::getWindowFlags() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FurnaceGUIRenderDX9::getMaxTextureWidth() {
|
||||
return maxWidth;
|
||||
}
|
||||
|
||||
int FurnaceGUIRenderDX9::getMaxTextureHeight() {
|
||||
return maxHeight;
|
||||
}
|
||||
|
||||
unsigned int FurnaceGUIRenderDX9::getTextureFormats() {
|
||||
return GUI_TEXFORMAT_ARGB32;
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderDX9::getBackendName() {
|
||||
return "DirectX 9";
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderDX9::getVendorName() {
|
||||
return vendorName.c_str();
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderDX9::getDeviceName() {
|
||||
return deviceName.c_str();
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderDX9::getAPIVersion() {
|
||||
return apiVersion.c_str();
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX9::setSwapInterval(int swapInt) {
|
||||
swapInterval=swapInt;
|
||||
}
|
||||
|
||||
// I would use caps but...
|
||||
bool FurnaceGUIRenderDX9::areTexturesSquare() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX9::preInit(const DivConfig& conf) {
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) {
|
||||
D3DADAPTER_IDENTIFIER9 adapterInfo;
|
||||
SDL_SysWMinfo sysWindow;
|
||||
|
||||
SDL_VERSION(&sysWindow.version);
|
||||
if (SDL_GetWindowWMInfo(win,&sysWindow)==SDL_FALSE) {
|
||||
logE("could not get window WM info! %s",SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
HWND window=(HWND)sysWindow.info.win.window;
|
||||
|
||||
iface=Direct3DCreate9(D3D_SDK_VERSION);
|
||||
if (iface==NULL) {
|
||||
logE("could not create Direct3D 9!");
|
||||
return false;
|
||||
}
|
||||
|
||||
priv=new FurnaceGUIRenderDX9Private;
|
||||
|
||||
SDL_GetWindowSize(win,&outW,&outH);
|
||||
|
||||
memset(&priv->present,0,sizeof(D3DPRESENT_PARAMETERS));
|
||||
priv->present.Windowed=TRUE;
|
||||
priv->present.SwapEffect=D3DSWAPEFFECT_DISCARD;
|
||||
priv->present.BackBufferWidth=outW;
|
||||
priv->present.BackBufferHeight=outH;
|
||||
priv->present.BackBufferCount=1;
|
||||
priv->present.BackBufferFormat=D3DFMT_UNKNOWN;
|
||||
//priv->present.EnableAutoDepthStencil=TRUE;
|
||||
//priv->present.AutoDepthStencilFormat=D3DFMT_D16;
|
||||
if (swapInt>0) {
|
||||
priv->present.PresentationInterval=D3DPRESENT_INTERVAL_ONE;
|
||||
} else {
|
||||
priv->present.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
}
|
||||
priv->present.hDeviceWindow=window;
|
||||
|
||||
HRESULT result=iface->GetAdapterIdentifier(D3DADAPTER_DEFAULT,0,&adapterInfo);
|
||||
|
||||
if (result==D3D_OK) {
|
||||
vendorName=fmt::sprintf("0x%.4X",adapterInfo.VendorId);
|
||||
deviceName=fmt::sprintf("%s (%s)",adapterInfo.Description,adapterInfo.DeviceName);
|
||||
apiVersion=fmt::sprintf("%.8X %.8X %s",adapterInfo.DriverVersion.HighPart,adapterInfo.DriverVersion.LowPart,adapterInfo.Driver);
|
||||
} else {
|
||||
logW("could not get adapter info! %.8x",result);
|
||||
}
|
||||
|
||||
result=iface->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,window,D3DCREATE_HARDWARE_VERTEXPROCESSING,&priv->present,&device);
|
||||
|
||||
if (result!=D3D_OK) {
|
||||
logW("no hardware vertex processing!");
|
||||
result=iface->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,window,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&priv->present,&device);
|
||||
if (result!=D3D_OK) {
|
||||
logE("could not create device! %.8x",result);
|
||||
iface->Release();
|
||||
iface=NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
D3DCAPS9 caps;
|
||||
|
||||
result=device->GetDeviceCaps(&caps);
|
||||
|
||||
if (result==D3D_OK) {
|
||||
supportsDynamicTex=(caps.Caps2&D3DCAPS2_DYNAMICTEXTURES);
|
||||
squareTex=(caps.TextureCaps&D3DPTEXTURECAPS_SQUAREONLY);
|
||||
supportsVSync=(caps.PresentationIntervals&D3DPRESENT_INTERVAL_ONE);
|
||||
maxWidth=caps.MaxTextureWidth;
|
||||
maxHeight=caps.MaxTextureHeight;
|
||||
|
||||
if (!supportsDynamicTex) {
|
||||
logI("no support for dynamic textures");
|
||||
}
|
||||
if (squareTex) {
|
||||
logI("square textures only");
|
||||
}
|
||||
}
|
||||
|
||||
result=device->CreateVertexBuffer(sizeof(WipeVertex)*4,0,D3DFVF_XYZ|D3DFVF_DIFFUSE,D3DPOOL_DEFAULT,&wipeBuf,NULL);
|
||||
|
||||
if (result!=D3D_OK) {
|
||||
logE("could not create wipe buffer! %.8x",result);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX9::initGUI(SDL_Window* win) {
|
||||
ImGui_ImplSDL2_InitForD3D(win);
|
||||
ImGui_ImplDX9_Init(device);
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderDX9::quit() {
|
||||
if (wipeBuf) {
|
||||
wipeBuf->Release();
|
||||
wipeBuf=NULL;
|
||||
}
|
||||
if (device) {
|
||||
device->Release();
|
||||
device=NULL;
|
||||
}
|
||||
if (iface) {
|
||||
iface->Release();
|
||||
iface=NULL;
|
||||
}
|
||||
priv->texPool.clear();
|
||||
dead=false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderDX9::quitGUI() {
|
||||
ImGui_ImplDX9_Shutdown();
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderDX9::isDead() {
|
||||
return dead;
|
||||
}
|
||||
102
src/gui/render/renderDX9.h
Normal file
102
src/gui/render/renderDX9.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2024 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"
|
||||
#ifdef INCLUDE_D3D9
|
||||
#include <d3d9.h>
|
||||
struct FurnaceGUIRenderDX9Private;
|
||||
#else
|
||||
typedef void IDirect3D9;
|
||||
typedef void IDirect3DVertexBuffer9;
|
||||
typedef void FurnaceGUIRenderDX9Private;
|
||||
#endif
|
||||
|
||||
class FurnaceGUIRenderDX9: public FurnaceGUIRender {
|
||||
IDirect3D9* iface;
|
||||
IDirect3DDevice9* device;
|
||||
FurnaceGUIRenderDX9Private* priv;
|
||||
IDirect3DVertexBuffer9* wipeBuf;
|
||||
|
||||
int outW, outH, swapInterval;
|
||||
|
||||
bool dead, haveScene, supportsDynamicTex, supportsVSync, mustResize, squareTex, inScene;
|
||||
|
||||
// SHADERS //
|
||||
|
||||
int maxWidth, maxHeight;
|
||||
String vendorName, deviceName, apiVersion;
|
||||
|
||||
public:
|
||||
ImTextureID getTextureID(FurnaceGUITexture* which);
|
||||
float getTextureU(FurnaceGUITexture* which);
|
||||
float getTextureV(FurnaceGUITexture* which);
|
||||
FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which);
|
||||
bool isTextureValid(FurnaceGUITexture* which);
|
||||
bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
|
||||
bool unlockTexture(FurnaceGUITexture* which);
|
||||
bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
|
||||
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true, FurnaceGUITextureFormat format=GUI_TEXFORMAT_ABGR32);
|
||||
bool destroyTexture(FurnaceGUITexture* which);
|
||||
void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
|
||||
void setBlendMode(FurnaceGUIBlendMode mode);
|
||||
void resized(const SDL_Event& ev);
|
||||
void clear(ImVec4 color);
|
||||
bool newFrame();
|
||||
bool canVSync();
|
||||
bool areTexturesSquare();
|
||||
void createFontsTexture();
|
||||
void destroyFontsTexture();
|
||||
void renderGUI();
|
||||
void wipe(float alpha);
|
||||
void present();
|
||||
bool getOutputSize(int& w, int& h);
|
||||
int getWindowFlags();
|
||||
int getMaxTextureWidth();
|
||||
int getMaxTextureHeight();
|
||||
unsigned int getTextureFormats();
|
||||
const char* getBackendName();
|
||||
const char* getVendorName();
|
||||
const char* getDeviceName();
|
||||
const char* getAPIVersion();
|
||||
void setSwapInterval(int swapInterval);
|
||||
void preInit(const DivConfig& conf);
|
||||
bool init(SDL_Window* win, int swapInterval);
|
||||
void initGUI(SDL_Window* win);
|
||||
void quitGUI();
|
||||
bool quit();
|
||||
bool isDead();
|
||||
FurnaceGUIRenderDX9():
|
||||
iface(NULL),
|
||||
device(NULL),
|
||||
priv(NULL),
|
||||
wipeBuf(NULL),
|
||||
outW(0),
|
||||
outH(0),
|
||||
swapInterval(1),
|
||||
dead(false),
|
||||
haveScene(false),
|
||||
supportsDynamicTex(false),
|
||||
supportsVSync(false),
|
||||
mustResize(false),
|
||||
squareTex(false),
|
||||
inScene(false),
|
||||
maxWidth(8192),
|
||||
maxHeight(8192) {
|
||||
}
|
||||
};
|
||||
|
|
@ -65,22 +65,24 @@ class FurnaceGLTexture: public FurnaceGUITexture {
|
|||
public:
|
||||
GLuint id;
|
||||
int width, height;
|
||||
FurnaceGUITextureFormat format;
|
||||
unsigned char* lockedData;
|
||||
FurnaceGLTexture():
|
||||
id(0),
|
||||
width(0),
|
||||
height(0),
|
||||
format(GUI_TEXFORMAT_UNKNOWN),
|
||||
lockedData(NULL) {}
|
||||
};
|
||||
|
||||
#ifdef USE_GLES
|
||||
const char* sh_wipe_srcV=
|
||||
const char* sh_wipe_srcV_ES2=
|
||||
"attribute vec4 fur_position;\n"
|
||||
"void main() {\n"
|
||||
" gl_Position=fur_position;\n"
|
||||
"}\n";
|
||||
|
||||
const char* sh_wipe_srcF=
|
||||
const char* sh_wipe_srcF_ES2=
|
||||
"uniform float uAlpha;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor=vec4(0.0,0.0,0.0,uAlpha);\n"
|
||||
|
|
@ -133,14 +135,14 @@ const char* sh_oscRender_srcF=
|
|||
" }\n"
|
||||
"}\n";
|
||||
#else
|
||||
const char* sh_wipe_srcV=
|
||||
const char* sh_wipe_srcV_130=
|
||||
"#version 130\n"
|
||||
"in vec4 fur_position;\n"
|
||||
"void main() {\n"
|
||||
" gl_Position=fur_position;\n"
|
||||
"}\n";
|
||||
|
||||
const char* sh_wipe_srcF=
|
||||
const char* sh_wipe_srcF_130=
|
||||
"#version 130\n"
|
||||
"uniform float uAlpha;\n"
|
||||
"out vec4 fur_FragColor;\n"
|
||||
|
|
@ -148,6 +150,20 @@ const char* sh_wipe_srcF=
|
|||
" fur_FragColor=vec4(0.0,0.0,0.0,uAlpha);\n"
|
||||
"}\n";
|
||||
|
||||
const char* sh_wipe_srcV_110=
|
||||
"#version 110\n"
|
||||
"attribute vec4 fur_position;\n"
|
||||
"void main() {\n"
|
||||
" gl_Position=fur_position;\n"
|
||||
"}\n";
|
||||
|
||||
const char* sh_wipe_srcF_110=
|
||||
"#version 110\n"
|
||||
"uniform float uAlpha;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor=vec4(0.0,0.0,0.0,uAlpha);\n"
|
||||
"}\n";
|
||||
|
||||
const char* sh_oscRender_srcV=
|
||||
"#version 130\n"
|
||||
"in vec4 fur_position;\n"
|
||||
|
|
@ -267,6 +283,11 @@ ImTextureID FurnaceGUIRenderGL::getTextureID(FurnaceGUITexture* which) {
|
|||
return (ImTextureID)ret;
|
||||
}
|
||||
|
||||
FurnaceGUITextureFormat FurnaceGUIRenderGL::getTextureFormat(FurnaceGUITexture* which) {
|
||||
FurnaceGLTexture* t=(FurnaceGLTexture*)which;
|
||||
return t->format;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderGL::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) {
|
||||
FurnaceGLTexture* t=(FurnaceGLTexture*)which;
|
||||
if (t->lockedData!=NULL) return false;
|
||||
|
|
@ -301,16 +322,26 @@ bool FurnaceGUIRenderGL::updateTexture(FurnaceGUITexture* which, void* data, int
|
|||
return true;
|
||||
}
|
||||
|
||||
FurnaceGUITexture* FurnaceGUIRenderGL::createTexture(bool dynamic, int width, int height) {
|
||||
FurnaceGUITexture* FurnaceGUIRenderGL::createTexture(bool dynamic, int width, int height, bool interpolate, FurnaceGUITextureFormat format) {
|
||||
if (format!=GUI_TEXFORMAT_ABGR32) {
|
||||
logE("unsupported texture format!");
|
||||
return NULL;
|
||||
}
|
||||
FurnaceGLTexture* t=new FurnaceGLTexture;
|
||||
C(glGenTextures(1,&t->id));
|
||||
C(glBindTexture(GL_TEXTURE_2D,t->id));
|
||||
C(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR));
|
||||
C(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR));
|
||||
if (interpolate) {
|
||||
C(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR));
|
||||
C(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR));
|
||||
} else {
|
||||
C(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST));
|
||||
C(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST));
|
||||
}
|
||||
C(glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,width,height,0,GL_RGBA,PIXEL_FORMAT,NULL));
|
||||
C(furActiveTexture(GL_TEXTURE0));
|
||||
t->width=width;
|
||||
t->height=height;
|
||||
t->format=format;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
|
@ -355,6 +386,10 @@ bool FurnaceGUIRenderGL::newFrame() {
|
|||
return ImGui_ImplOpenGL3_NewFrame();
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderGL::canVSync() {
|
||||
return swapIntervalSet;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL::createFontsTexture() {
|
||||
ImGui_ImplOpenGL3_CreateFontsTexture();
|
||||
}
|
||||
|
|
@ -398,6 +433,7 @@ void FurnaceGUIRenderGL::wipe(float alpha) {
|
|||
}
|
||||
|
||||
void FurnaceGUIRenderGL::drawOsc(float* data, size_t len, ImVec2 pos0, ImVec2 pos1, ImVec4 color, ImVec2 canvasSize, float lineWidth) {
|
||||
if (!sh_oscRender_have) return;
|
||||
if (!furUseProgram) return;
|
||||
if (!furUniform4fv) return;
|
||||
if (!furUniform1f) return;
|
||||
|
|
@ -522,31 +558,75 @@ int FurnaceGUIRenderGL::getWindowFlags() {
|
|||
return SDL_WINDOW_OPENGL;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL::preInit() {
|
||||
int FurnaceGUIRenderGL::getMaxTextureWidth() {
|
||||
return maxWidth;
|
||||
}
|
||||
|
||||
int FurnaceGUIRenderGL::getMaxTextureHeight() {
|
||||
return maxHeight;
|
||||
}
|
||||
|
||||
unsigned int FurnaceGUIRenderGL::getTextureFormats() {
|
||||
return GUI_TEXFORMAT_ABGR32;
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderGL::getBackendName() {
|
||||
return backendName.c_str();
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderGL::getVendorName() {
|
||||
return vendorName.c_str();
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderGL::getDeviceName() {
|
||||
return deviceName.c_str();
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderGL::getAPIVersion() {
|
||||
return apiVersion.c_str();
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL::setSwapInterval(int swapInterval) {
|
||||
SDL_GL_SetSwapInterval(swapInterval);
|
||||
if (swapInterval>0 && SDL_GL_GetSwapInterval()==0) {
|
||||
swapIntervalSet=false;
|
||||
logW("tried to enable VSync but couldn't!");
|
||||
} else {
|
||||
swapIntervalSet=true;
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL::preInit(const DivConfig& conf) {
|
||||
#if defined(USE_GLES)
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS,0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,SDL_GL_CONTEXT_PROFILE_ES);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,0);
|
||||
#elif defined(__APPLE__)
|
||||
// not recommended...
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS,SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,2);
|
||||
if (glVer==2) {
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,0);
|
||||
} else {
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,2);
|
||||
}
|
||||
#else
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS,0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,glVer);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,0);
|
||||
#endif
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE,8);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,8);
|
||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,0);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,24);
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE,conf.getInt("glRedSize",8));
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,conf.getInt("glGreenSize",8));
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,conf.getInt("glBlueSize",8));
|
||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,conf.getInt("glAlphaSize",0));
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,conf.getInt("glDoubleBuffer",1));
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,conf.getInt("glDepthSize",24));
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE,conf.getInt("glStencilSize",0));
|
||||
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE,conf.getInt("glBufferSize",32));
|
||||
}
|
||||
|
||||
#define LOAD_PROC_MANDATORY(_v,_t,_s) \
|
||||
|
|
@ -562,14 +642,20 @@ void FurnaceGUIRenderGL::preInit() {
|
|||
logW(_s " not found"); \
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderGL::init(SDL_Window* win) {
|
||||
bool FurnaceGUIRenderGL::init(SDL_Window* win, int swapInterval) {
|
||||
sdlWin=win;
|
||||
context=SDL_GL_CreateContext(win);
|
||||
if (context==NULL) {
|
||||
return false;
|
||||
}
|
||||
SDL_GL_MakeCurrent(win,context);
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
SDL_GL_SetSwapInterval(swapInterval);
|
||||
if (swapInterval>0 && SDL_GL_GetSwapInterval()==0) {
|
||||
swapIntervalSet=false;
|
||||
logW("tried to enable VSync but couldn't!");
|
||||
} else {
|
||||
swapIntervalSet=true;
|
||||
}
|
||||
|
||||
LOAD_PROC_MANDATORY(furGenBuffers,PFNGLGENBUFFERSPROC,"glGenBuffers");
|
||||
LOAD_PROC_MANDATORY(furBindBuffer,PFNGLBINDBUFFERPROC,"glBindBuffer");
|
||||
|
|
@ -600,25 +686,56 @@ bool FurnaceGUIRenderGL::init(SDL_Window* win) {
|
|||
|
||||
#ifndef USE_GLES
|
||||
LOAD_PROC_OPTIONAL(furGetGraphicsResetStatusARB,PFNGLGETGRAPHICSRESETSTATUSARBPROC,"glGetGraphicsResetStatusARB");
|
||||
#else
|
||||
backendName="OpenGL ES 2.0";
|
||||
#endif
|
||||
|
||||
// information
|
||||
const char* next=(const char*)glGetString(GL_VENDOR);
|
||||
if (next==NULL) {
|
||||
vendorName="???";
|
||||
} else {
|
||||
vendorName=next;
|
||||
}
|
||||
next=(const char*)glGetString(GL_RENDERER);
|
||||
if (next==NULL) {
|
||||
deviceName="???";
|
||||
} else {
|
||||
deviceName=next;
|
||||
}
|
||||
next=(const char*)glGetString(GL_VERSION);
|
||||
if (next==NULL) {
|
||||
apiVersion="???";
|
||||
} else {
|
||||
apiVersion=next;
|
||||
}
|
||||
|
||||
int maxSize=1024;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxSize);
|
||||
|
||||
maxWidth=maxSize;
|
||||
maxHeight=maxSize;
|
||||
|
||||
// texture for osc renderer
|
||||
C(glGenTextures(1,&oscDataTex));
|
||||
if (glVer==3) {
|
||||
C(glGenTextures(1,&oscDataTex));
|
||||
#ifdef USE_GLES
|
||||
C(glBindTexture(GL_TEXTURE_2D,oscDataTex));
|
||||
C(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST));
|
||||
C(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST));
|
||||
C(glTexImage2D(GL_TEXTURE_2D,0,GL_RED_EXT,2048,1,0,GL_RED_EXT,GL_FLOAT,NULL));
|
||||
C(glBindTexture(GL_TEXTURE_2D,oscDataTex));
|
||||
C(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST));
|
||||
C(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST));
|
||||
C(glTexImage2D(GL_TEXTURE_2D,0,GL_RED_EXT,2048,1,0,GL_RED_EXT,GL_FLOAT,NULL));
|
||||
#else
|
||||
C(glBindTexture(GL_TEXTURE_1D,oscDataTex));
|
||||
C(glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER,GL_NEAREST));
|
||||
C(glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MAG_FILTER,GL_NEAREST));
|
||||
C(glTexImage1D(GL_TEXTURE_1D,0,GL_RED,2048,0,GL_RED,GL_FLOAT,NULL));
|
||||
C(glBindTexture(GL_TEXTURE_1D,oscDataTex));
|
||||
C(glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER,GL_NEAREST));
|
||||
C(glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MAG_FILTER,GL_NEAREST));
|
||||
C(glTexImage1D(GL_TEXTURE_1D,0,GL_RED,2048,0,GL_RED,GL_FLOAT,NULL));
|
||||
#endif
|
||||
C(furActiveTexture(GL_TEXTURE0));
|
||||
C(furActiveTexture(GL_TEXTURE0));
|
||||
}
|
||||
|
||||
// create shaders
|
||||
if ((sh_wipe_have=createShader(sh_wipe_srcV,sh_wipe_srcF,sh_wipe_vertex,sh_wipe_fragment,sh_wipe_program,sh_wipe_attrib))==true) {
|
||||
#ifdef USE_GLES
|
||||
if ((sh_wipe_have=createShader(sh_wipe_srcV_ES2,sh_wipe_srcF_ES2,sh_wipe_vertex,sh_wipe_fragment,sh_wipe_program,sh_wipe_attrib))==true) {
|
||||
sh_wipe_uAlpha=furGetUniformLocation(sh_wipe_program,"uAlpha");
|
||||
}
|
||||
|
||||
|
|
@ -628,34 +745,32 @@ bool FurnaceGUIRenderGL::init(SDL_Window* win) {
|
|||
sh_oscRender_uResolution=furGetUniformLocation(sh_oscRender_program,"uResolution");
|
||||
sh_oscRender_oscVal=furGetUniformLocation(sh_oscRender_program,"oscVal");
|
||||
}
|
||||
#else
|
||||
if (glVer==3) {
|
||||
if ((sh_wipe_have=createShader(sh_wipe_srcV_130,sh_wipe_srcF_130,sh_wipe_vertex,sh_wipe_fragment,sh_wipe_program,sh_wipe_attrib))==true) {
|
||||
sh_wipe_uAlpha=furGetUniformLocation(sh_wipe_program,"uAlpha");
|
||||
}
|
||||
|
||||
if ((sh_oscRender_have=createShader(sh_oscRender_srcV,sh_oscRender_srcF,sh_oscRender_vertex,sh_oscRender_fragment,sh_oscRender_program,sh_oscRender_attrib))==true) {
|
||||
sh_oscRender_uColor=furGetUniformLocation(sh_oscRender_program,"uColor");
|
||||
sh_oscRender_uLineWidth=furGetUniformLocation(sh_oscRender_program,"uLineWidth");
|
||||
sh_oscRender_uResolution=furGetUniformLocation(sh_oscRender_program,"uResolution");
|
||||
sh_oscRender_oscVal=furGetUniformLocation(sh_oscRender_program,"oscVal");
|
||||
}
|
||||
} else {
|
||||
if ((sh_wipe_have=createShader(sh_wipe_srcV_110,sh_wipe_srcF_110,sh_wipe_vertex,sh_wipe_fragment,sh_wipe_program,sh_wipe_attrib))==true) {
|
||||
sh_wipe_uAlpha=furGetUniformLocation(sh_wipe_program,"uAlpha");
|
||||
}
|
||||
|
||||
sh_oscRender_have=false;
|
||||
}
|
||||
#endif
|
||||
|
||||
C(furGenBuffers(1,&quadBuf));
|
||||
C(furGenBuffers(1,&oscVertexBuf));
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderGL::getStupidFragment() {
|
||||
return sh_oscRender_srcF;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderGL::regenOscShader(const char* fragment) {
|
||||
if (sh_oscRender_have) {
|
||||
furDeleteProgram(sh_oscRender_program);
|
||||
furDeleteShader(sh_oscRender_vertex);
|
||||
furDeleteShader(sh_oscRender_fragment);
|
||||
}
|
||||
|
||||
if ((sh_oscRender_have=createShader(sh_oscRender_srcV,fragment,sh_oscRender_vertex,sh_oscRender_fragment,sh_oscRender_program,sh_oscRender_attrib))==true) {
|
||||
sh_oscRender_uColor=furGetUniformLocation(sh_oscRender_program,"uColor");
|
||||
sh_oscRender_uLineWidth=furGetUniformLocation(sh_oscRender_program,"uLineWidth");
|
||||
sh_oscRender_uResolution=furGetUniformLocation(sh_oscRender_program,"uResolution");
|
||||
sh_oscRender_oscVal=furGetUniformLocation(sh_oscRender_program,"oscVal");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL::initGUI(SDL_Window* win) {
|
||||
ImGui_ImplSDL2_InitForOpenGL(win,context);
|
||||
ImGui_ImplOpenGL3_Init();
|
||||
|
|
@ -681,3 +796,14 @@ bool FurnaceGUIRenderGL::isDead() {
|
|||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL::setVersion(unsigned char ver) {
|
||||
glVer=ver;
|
||||
if (glVer==3) {
|
||||
backendName="OpenGL 3.0";
|
||||
} else if (glVer==2) {
|
||||
backendName="OpenGL 2.0";
|
||||
} else {
|
||||
backendName="OpenGL BUG.REPORT";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,21 +46,27 @@ class FurnaceGUIRenderGL: public FurnaceGUIRender {
|
|||
int sh_oscRender_oscVal;
|
||||
bool sh_oscRender_have;
|
||||
|
||||
bool swapIntervalSet;
|
||||
unsigned char glVer;
|
||||
|
||||
int maxWidth, maxHeight;
|
||||
String backendName, vendorName, deviceName, apiVersion;
|
||||
|
||||
bool createShader(const char* vertexS, const char* fragmentS, int& vertex, int& fragment, int& program, const char** attribNames);
|
||||
|
||||
public:
|
||||
ImTextureID getTextureID(FurnaceGUITexture* which);
|
||||
FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which);
|
||||
bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
|
||||
bool unlockTexture(FurnaceGUITexture* which);
|
||||
bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
|
||||
FurnaceGUITexture* createTexture(bool dynamic, int width, int height);
|
||||
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true, FurnaceGUITextureFormat format=GUI_TEXFORMAT_ABGR32);
|
||||
bool destroyTexture(FurnaceGUITexture* which);
|
||||
void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
|
||||
void setBlendMode(FurnaceGUIBlendMode mode);
|
||||
const char* getStupidFragment();
|
||||
bool regenOscShader(const char* fragment);
|
||||
void clear(ImVec4 color);
|
||||
bool newFrame();
|
||||
bool canVSync();
|
||||
void createFontsTexture();
|
||||
void destroyFontsTexture();
|
||||
void renderGUI();
|
||||
|
|
@ -70,15 +76,29 @@ class FurnaceGUIRenderGL: public FurnaceGUIRender {
|
|||
bool getOutputSize(int& w, int& h);
|
||||
bool supportsDrawOsc();
|
||||
int getWindowFlags();
|
||||
void preInit();
|
||||
bool init(SDL_Window* win);
|
||||
int getMaxTextureWidth();
|
||||
int getMaxTextureHeight();
|
||||
unsigned int getTextureFormats();
|
||||
const char* getBackendName();
|
||||
const char* getVendorName();
|
||||
const char* getDeviceName();
|
||||
const char* getAPIVersion();
|
||||
void setSwapInterval(int swapInterval);
|
||||
void preInit(const DivConfig& conf);
|
||||
bool init(SDL_Window* win, int swapInterval);
|
||||
void initGUI(SDL_Window* win);
|
||||
void quitGUI();
|
||||
bool quit();
|
||||
bool isDead();
|
||||
void setVersion(unsigned char ver);
|
||||
FurnaceGUIRenderGL():
|
||||
context(NULL),
|
||||
sdlWin(NULL) {
|
||||
sdlWin(NULL),
|
||||
swapIntervalSet(true),
|
||||
glVer(3),
|
||||
maxWidth(0),
|
||||
maxHeight(0),
|
||||
backendName("What?") {
|
||||
memset(quadVertex,0,4*3*sizeof(float));
|
||||
memset(oscVertex,0,4*5*sizeof(float));
|
||||
memset(oscData,0,2048*sizeof(float));
|
||||
|
|
|
|||
361
src/gui/render/renderGL1.cpp
Normal file
361
src/gui/render/renderGL1.cpp
Normal file
|
|
@ -0,0 +1,361 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2024 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 "renderGL1.h"
|
||||
#include "../../ta-log.h"
|
||||
#include "SDL_opengl.h"
|
||||
#include "backends/imgui_impl_opengl2.h"
|
||||
#include "../engine/bsr.h"
|
||||
|
||||
#define C(x) x; if (glGetError()!=GL_NO_ERROR) logW("OpenGL error in %s:%d: " #x,__FILE__,__LINE__);
|
||||
|
||||
class FurnaceGL1Texture: public FurnaceGUITexture {
|
||||
public:
|
||||
GLuint id;
|
||||
int width, height, widthReal, heightReal;
|
||||
FurnaceGUITextureFormat format;
|
||||
unsigned char* lockedData;
|
||||
FurnaceGL1Texture():
|
||||
id(0),
|
||||
width(0),
|
||||
height(0),
|
||||
widthReal(0),
|
||||
heightReal(0),
|
||||
format(GUI_TEXFORMAT_UNKNOWN),
|
||||
lockedData(NULL) {}
|
||||
};
|
||||
|
||||
ImTextureID FurnaceGUIRenderGL1::getTextureID(FurnaceGUITexture* which) {
|
||||
intptr_t ret=((FurnaceGL1Texture*)which)->id;
|
||||
return (ImTextureID)ret;
|
||||
}
|
||||
|
||||
float FurnaceGUIRenderGL1::getTextureU(FurnaceGUITexture* which) {
|
||||
FurnaceGL1Texture* t=(FurnaceGL1Texture*)which;
|
||||
if (t->widthReal<1) return 0.0f;
|
||||
return (float)t->width/(float)t->widthReal;
|
||||
}
|
||||
|
||||
float FurnaceGUIRenderGL1::getTextureV(FurnaceGUITexture* which) {
|
||||
FurnaceGL1Texture* t=(FurnaceGL1Texture*)which;
|
||||
if (t->heightReal<1) return 0.0f;
|
||||
return (float)t->height/(float)t->heightReal;
|
||||
}
|
||||
|
||||
FurnaceGUITextureFormat FurnaceGUIRenderGL1::getTextureFormat(FurnaceGUITexture* which) {
|
||||
FurnaceGL1Texture* t=(FurnaceGL1Texture*)which;
|
||||
return t->format;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderGL1::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) {
|
||||
FurnaceGL1Texture* t=(FurnaceGL1Texture*)which;
|
||||
if (t->lockedData!=NULL) return false;
|
||||
t->lockedData=new unsigned char[t->widthReal*t->heightReal*4];
|
||||
|
||||
*data=t->lockedData;
|
||||
*pitch=t->widthReal*4;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderGL1::unlockTexture(FurnaceGUITexture* which) {
|
||||
FurnaceGL1Texture* t=(FurnaceGL1Texture*)which;
|
||||
if (t->lockedData==NULL) return false;
|
||||
|
||||
C(glBindTexture(GL_TEXTURE_2D,t->id));
|
||||
C(glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,t->widthReal,t->heightReal,0,GL_RGBA,GL_UNSIGNED_BYTE,t->lockedData));
|
||||
|
||||
C(glFlush());
|
||||
delete[] t->lockedData;
|
||||
t->lockedData=NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderGL1::updateTexture(FurnaceGUITexture* which, void* data, int pitch) {
|
||||
FurnaceGL1Texture* t=(FurnaceGL1Texture*)which;
|
||||
|
||||
if (t->width*4!=pitch) return false;
|
||||
|
||||
logV("GL1 updateTexture...");
|
||||
|
||||
C(glBindTexture(GL_TEXTURE_2D,t->id));
|
||||
C(glTexSubImage2D(GL_TEXTURE_2D,0,0,0,t->width,t->height,GL_RGBA,GL_UNSIGNED_BYTE,data));
|
||||
return true;
|
||||
}
|
||||
|
||||
FurnaceGUITexture* FurnaceGUIRenderGL1::createTexture(bool dynamic, int width, int height, bool interpolate, FurnaceGUITextureFormat format) {
|
||||
if (format!=GUI_TEXFORMAT_ABGR32) {
|
||||
logE("unsupported texture format!");
|
||||
return NULL;
|
||||
}
|
||||
FurnaceGL1Texture* t=new FurnaceGL1Texture;
|
||||
C(glGenTextures(1,&t->id));
|
||||
C(glBindTexture(GL_TEXTURE_2D,t->id));
|
||||
if (interpolate) {
|
||||
C(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR));
|
||||
C(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR));
|
||||
} else {
|
||||
C(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST));
|
||||
C(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST));
|
||||
}
|
||||
|
||||
int widthReal=width;
|
||||
int heightReal=height;
|
||||
|
||||
if ((widthReal&(widthReal-1))!=0) {
|
||||
widthReal=1<<bsr(width);
|
||||
}
|
||||
if ((heightReal&(heightReal-1))!=0) {
|
||||
heightReal=1<<bsr(height);
|
||||
}
|
||||
logV("width: %d (requested)... %d (actual)",width,widthReal);
|
||||
logV("height: %d (requested)... %d (actual)",height,heightReal);
|
||||
|
||||
C(glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,widthReal,heightReal,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL));
|
||||
t->width=width;
|
||||
t->height=height;
|
||||
t->widthReal=widthReal;
|
||||
t->heightReal=heightReal;
|
||||
t->format=format;
|
||||
return t;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderGL1::destroyTexture(FurnaceGUITexture* which) {
|
||||
FurnaceGL1Texture* t=(FurnaceGL1Texture*)which;
|
||||
C(glDeleteTextures(1,&t->id));
|
||||
delete t;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL1::setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode) {
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL1::setBlendMode(FurnaceGUIBlendMode mode) {
|
||||
switch (mode) {
|
||||
case GUI_BLEND_MODE_NONE:
|
||||
C(glBlendFunc(GL_ONE,GL_ZERO));
|
||||
C(glDisable(GL_BLEND));
|
||||
break;
|
||||
case GUI_BLEND_MODE_BLEND:
|
||||
C(glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA));
|
||||
C(glEnable(GL_BLEND));
|
||||
break;
|
||||
case GUI_BLEND_MODE_ADD:
|
||||
C(glBlendFunc(GL_SRC_ALPHA,GL_ONE));
|
||||
C(glEnable(GL_BLEND));
|
||||
break;
|
||||
case GUI_BLEND_MODE_MULTIPLY:
|
||||
C(glBlendFunc(GL_ZERO,GL_SRC_COLOR));
|
||||
C(glEnable(GL_BLEND));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL1::clear(ImVec4 color) {
|
||||
SDL_GL_MakeCurrent(sdlWin,context);
|
||||
C(glClearColor(color.x,color.y,color.z,color.w));
|
||||
C(glClear(GL_COLOR_BUFFER_BIT));
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderGL1::newFrame() {
|
||||
return ImGui_ImplOpenGL2_NewFrame();
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderGL1::canVSync() {
|
||||
return swapIntervalSet;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL1::createFontsTexture() {
|
||||
ImGui_ImplOpenGL2_CreateFontsTexture();
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL1::destroyFontsTexture() {
|
||||
ImGui_ImplOpenGL2_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL1::renderGUI() {
|
||||
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL1::wipe(float alpha) {
|
||||
C(glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA));
|
||||
C(glEnable(GL_BLEND));
|
||||
|
||||
C(glBindTexture(GL_TEXTURE_2D,0));
|
||||
C(glBegin(GL_TRIANGLE_STRIP));
|
||||
C(glColor4f(0.0,0.0,0.0,alpha));
|
||||
C(glNormal3f(0.0f,0.0f,0.0f));
|
||||
C(glVertex3f(-1.0f,-1.0f,0.0f));
|
||||
C(glNormal3f(1.0f,0.0f,0.0f));
|
||||
C(glVertex3f(1.0f,-1.0f,0.0f));
|
||||
C(glNormal3f(0.0f,1.0f,0.0f));
|
||||
C(glVertex3f(-1.0f,1.0f,0.0f));
|
||||
C(glNormal3f(1.0f,1.0f,0.0f));
|
||||
C(glVertex3f(1.0f,1.0f,0.0f));
|
||||
C(glEnd());
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL1::present() {
|
||||
SDL_GL_SwapWindow(sdlWin);
|
||||
C(glFlush());
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderGL1::getOutputSize(int& w, int& h) {
|
||||
SDL_GL_GetDrawableSize(sdlWin,&w,&h);
|
||||
return true;
|
||||
}
|
||||
|
||||
int FurnaceGUIRenderGL1::getWindowFlags() {
|
||||
return SDL_WINDOW_OPENGL;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderGL1::areTexturesSquare() {
|
||||
return true;
|
||||
}
|
||||
|
||||
int FurnaceGUIRenderGL1::getMaxTextureWidth() {
|
||||
return maxWidth;
|
||||
}
|
||||
|
||||
int FurnaceGUIRenderGL1::getMaxTextureHeight() {
|
||||
return maxHeight;
|
||||
}
|
||||
|
||||
unsigned int FurnaceGUIRenderGL1::getTextureFormats() {
|
||||
return GUI_TEXFORMAT_ABGR32;
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderGL1::getBackendName() {
|
||||
return "OpenGL 1.1";
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderGL1::getVendorName() {
|
||||
return vendorName.c_str();
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderGL1::getDeviceName() {
|
||||
return deviceName.c_str();
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderGL1::getAPIVersion() {
|
||||
return apiVersion.c_str();
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL1::setSwapInterval(int swapInterval) {
|
||||
SDL_GL_SetSwapInterval(swapInterval);
|
||||
if (swapInterval>0 && SDL_GL_GetSwapInterval()==0) {
|
||||
swapIntervalSet=false;
|
||||
logW("tried to enable VSync but couldn't!");
|
||||
} else {
|
||||
swapIntervalSet=true;
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL1::preInit(const DivConfig& conf) {
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS,0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,1);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,1);
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE,conf.getInt("glRedSize",8));
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,conf.getInt("glGreenSize",8));
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,conf.getInt("glBlueSize",8));
|
||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,conf.getInt("glAlphaSize",0));
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,conf.getInt("glDoubleBuffer",1));
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,conf.getInt("glDepthSize",24));
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE,conf.getInt("glStencilSize",0));
|
||||
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE,conf.getInt("glBufferSize",32));
|
||||
}
|
||||
|
||||
#define LOAD_PROC_MANDATORY(_v,_t,_s) \
|
||||
_v=(_t)SDL_GL_GetProcAddress(_s); \
|
||||
if (!_v) { \
|
||||
logE(_s " not found"); \
|
||||
return false; \
|
||||
}
|
||||
|
||||
#define LOAD_PROC_OPTIONAL(_v,_t,_s) \
|
||||
_v=(_t)SDL_GL_GetProcAddress(_s); \
|
||||
if (!_v) { \
|
||||
logW(_s " not found"); \
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderGL1::init(SDL_Window* win, int swapInterval) {
|
||||
sdlWin=win;
|
||||
context=SDL_GL_CreateContext(win);
|
||||
if (context==NULL) {
|
||||
return false;
|
||||
}
|
||||
SDL_GL_MakeCurrent(win,context);
|
||||
SDL_GL_SetSwapInterval(swapInterval);
|
||||
if (swapInterval>0 && SDL_GL_GetSwapInterval()==0) {
|
||||
swapIntervalSet=false;
|
||||
logW("tried to enable VSync but couldn't!");
|
||||
} else {
|
||||
swapIntervalSet=true;
|
||||
}
|
||||
|
||||
const char* next=(const char*)glGetString(GL_VENDOR);
|
||||
if (next==NULL) {
|
||||
vendorName="???";
|
||||
} else {
|
||||
vendorName=next;
|
||||
}
|
||||
next=(const char*)glGetString(GL_RENDERER);
|
||||
if (next==NULL) {
|
||||
deviceName="???";
|
||||
} else {
|
||||
deviceName=next;
|
||||
}
|
||||
next=(const char*)glGetString(GL_VERSION);
|
||||
if (next==NULL) {
|
||||
apiVersion="???";
|
||||
} else {
|
||||
apiVersion=next;
|
||||
}
|
||||
|
||||
int maxSize=1024;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxSize);
|
||||
|
||||
maxWidth=maxSize;
|
||||
maxHeight=maxSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL1::initGUI(SDL_Window* win) {
|
||||
ImGui_ImplSDL2_InitForOpenGL(win,context);
|
||||
ImGui_ImplOpenGL2_Init();
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderGL1::quit() {
|
||||
if (context==NULL) return false;
|
||||
SDL_GL_DeleteContext(context);
|
||||
context=NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderGL1::quitGUI() {
|
||||
ImGui_ImplOpenGL2_Shutdown();
|
||||
}
|
||||
|
||||
// sadly, OpenGL 1.1 doesn't have the ability to recover from death...
|
||||
bool FurnaceGUIRenderGL1::isDead() {
|
||||
return false;
|
||||
}
|
||||
75
src/gui/render/renderGL1.h
Normal file
75
src/gui/render/renderGL1.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2024 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"
|
||||
|
||||
class FurnaceGUIRenderGL1: public FurnaceGUIRender {
|
||||
SDL_GLContext context;
|
||||
SDL_Window* sdlWin;
|
||||
|
||||
bool swapIntervalSet;
|
||||
|
||||
int maxWidth, maxHeight;
|
||||
String vendorName, deviceName, apiVersion;
|
||||
|
||||
public:
|
||||
ImTextureID getTextureID(FurnaceGUITexture* which);
|
||||
float getTextureU(FurnaceGUITexture* which);
|
||||
float getTextureV(FurnaceGUITexture* which);
|
||||
FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which);
|
||||
bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
|
||||
bool unlockTexture(FurnaceGUITexture* which);
|
||||
bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
|
||||
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true, FurnaceGUITextureFormat format=GUI_TEXFORMAT_ABGR32);
|
||||
bool destroyTexture(FurnaceGUITexture* which);
|
||||
void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
|
||||
void setBlendMode(FurnaceGUIBlendMode mode);
|
||||
void clear(ImVec4 color);
|
||||
bool newFrame();
|
||||
bool canVSync();
|
||||
bool areTexturesSquare();
|
||||
void createFontsTexture();
|
||||
void destroyFontsTexture();
|
||||
void renderGUI();
|
||||
void wipe(float alpha);
|
||||
void present();
|
||||
bool getOutputSize(int& w, int& h);
|
||||
int getWindowFlags();
|
||||
int getMaxTextureWidth();
|
||||
int getMaxTextureHeight();
|
||||
unsigned int getTextureFormats();
|
||||
const char* getBackendName();
|
||||
const char* getVendorName();
|
||||
const char* getDeviceName();
|
||||
const char* getAPIVersion();
|
||||
void setSwapInterval(int swapInterval);
|
||||
void preInit(const DivConfig& conf);
|
||||
bool init(SDL_Window* win, int swapInterval);
|
||||
void initGUI(SDL_Window* win);
|
||||
void quitGUI();
|
||||
bool quit();
|
||||
bool isDead();
|
||||
FurnaceGUIRenderGL1():
|
||||
context(NULL),
|
||||
sdlWin(NULL),
|
||||
swapIntervalSet(true),
|
||||
maxWidth(0),
|
||||
maxHeight(0) {
|
||||
}
|
||||
};
|
||||
70
src/gui/render/renderMetal.h
Normal file
70
src/gui/render/renderMetal.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
* 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"
|
||||
|
||||
struct FurnaceGUIRenderMetalPrivate;
|
||||
|
||||
class FurnaceGUIRenderMetal: public FurnaceGUIRender {
|
||||
SDL_Renderer* sdlRend;
|
||||
FurnaceGUIRenderMetalPrivate* priv;
|
||||
bool swapIntervalSet, bigTextures;
|
||||
String vendorName, deviceName, apiVersion;
|
||||
public:
|
||||
ImTextureID getTextureID(FurnaceGUITexture* which);
|
||||
FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which);
|
||||
bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
|
||||
bool unlockTexture(FurnaceGUITexture* which);
|
||||
bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
|
||||
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true, FurnaceGUITextureFormat format=GUI_TEXFORMAT_ABGR32);
|
||||
bool destroyTexture(FurnaceGUITexture* which);
|
||||
void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
|
||||
void setBlendMode(FurnaceGUIBlendMode mode);
|
||||
void clear(ImVec4 color);
|
||||
bool newFrame();
|
||||
bool canVSync();
|
||||
void createFontsTexture();
|
||||
void destroyFontsTexture();
|
||||
void renderGUI();
|
||||
void wipe(float alpha);
|
||||
void present();
|
||||
bool getOutputSize(int& w, int& h);
|
||||
int getWindowFlags();
|
||||
int getMaxTextureWidth();
|
||||
int getMaxTextureHeight();
|
||||
unsigned int getTextureFormats();
|
||||
const char* getBackendName();
|
||||
const char* getVendorName();
|
||||
const char* getDeviceName();
|
||||
const char* getAPIVersion();
|
||||
void setSwapInterval(int swapInterval);
|
||||
void preInit(const DivConfig& conf);
|
||||
bool init(SDL_Window* win, int swapInterval);
|
||||
void initGUI(SDL_Window* win);
|
||||
void quitGUI();
|
||||
bool quit();
|
||||
FurnaceGUIRenderMetal():
|
||||
sdlRend(NULL),
|
||||
priv(NULL),
|
||||
swapIntervalSet(false),
|
||||
bigTextures(false),
|
||||
vendorName("Unknown"),
|
||||
deviceName("Unknown Graphics Device"),
|
||||
apiVersion("???") {}
|
||||
};
|
||||
332
src/gui/render/renderMetal.mm
Normal file
332
src/gui/render/renderMetal.mm
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
/**
|
||||
* 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 "renderMetal.h"
|
||||
#include "backends/imgui_impl_metal.h"
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
|
||||
struct FurnaceGUIRenderMetalPrivate {
|
||||
CAMetalLayer* context;
|
||||
id<MTLCommandQueue> cmdQueue;
|
||||
id<MTLCommandBuffer> cmdBuf;
|
||||
id<MTLRenderCommandEncoder> renderEncoder;
|
||||
id<CAMetalDrawable> drawable;
|
||||
MTLRenderPassDescriptor* renderPass;
|
||||
|
||||
FurnaceGUIRenderMetalPrivate():
|
||||
context(NULL),
|
||||
cmdQueue(NULL),
|
||||
cmdBuf(NULL),
|
||||
renderEncoder(NULL),
|
||||
drawable(NULL),
|
||||
renderPass(NULL) {}
|
||||
};
|
||||
|
||||
class FurnaceMetalTexture: public FurnaceGUITexture {
|
||||
public:
|
||||
id<MTLTexture> tex;
|
||||
int width, height;
|
||||
FurnaceGUITextureFormat format;
|
||||
unsigned char* lockedData;
|
||||
FurnaceMetalTexture():
|
||||
tex(NULL),
|
||||
width(0),
|
||||
height(0),
|
||||
format(GUI_TEXFORMAT_UNKNOWN),
|
||||
lockedData(NULL) {}
|
||||
};
|
||||
|
||||
ImTextureID FurnaceGUIRenderMetal::getTextureID(FurnaceGUITexture* which) {
|
||||
FurnaceMetalTexture* t=(FurnaceMetalTexture*)which;
|
||||
return t->tex;
|
||||
}
|
||||
|
||||
FurnaceGUITextureFormat FurnaceGUIRenderMetal::getTextureFormat(FurnaceGUITexture* which) {
|
||||
FurnaceMetalTexture* t=(FurnaceMetalTexture*)which;
|
||||
return t->format;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderMetal::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) {
|
||||
FurnaceMetalTexture* t=(FurnaceMetalTexture*)which;
|
||||
if (t->lockedData!=NULL) return false;
|
||||
t->lockedData=new unsigned char[t->width*t->height*4];
|
||||
|
||||
*data=t->lockedData;
|
||||
*pitch=t->width*4;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderMetal::unlockTexture(FurnaceGUITexture* which) {
|
||||
FurnaceMetalTexture* t=(FurnaceMetalTexture*)which;
|
||||
if (t->lockedData==NULL) return false;
|
||||
|
||||
[t->tex replaceRegion:MTLRegionMake2D(0,0,(NSUInteger)t->width,(NSUInteger)t->height) mipmapLevel:0 withBytes:t->lockedData bytesPerRow:(NSUInteger)t->width*4];
|
||||
delete[] t->lockedData;
|
||||
t->lockedData=NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderMetal::updateTexture(FurnaceGUITexture* which, void* data, int pitch) {
|
||||
FurnaceMetalTexture* t=(FurnaceMetalTexture*)which;
|
||||
[t->tex replaceRegion:MTLRegionMake2D(0,0,(NSUInteger)t->width,(NSUInteger)t->height) mipmapLevel:0 withBytes:data bytesPerRow:(NSUInteger)pitch];
|
||||
return true;
|
||||
}
|
||||
|
||||
FurnaceGUITexture* FurnaceGUIRenderMetal::createTexture(bool dynamic, int width, int height, bool interpolate, FurnaceGUITextureFormat format) {
|
||||
if (format!=GUI_TEXFORMAT_ABGR32) {
|
||||
logE("unsupported texture format!");
|
||||
return NULL;
|
||||
}
|
||||
MTLTextureDescriptor* texDesc=[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm width:(NSUInteger)width height:(NSUInteger)height mipmapped:NO];
|
||||
texDesc.usage=MTLTextureUsageShaderRead;
|
||||
texDesc.storageMode=MTLStorageModeManaged;
|
||||
|
||||
id<MTLTexture> texture=[priv->context.device newTextureWithDescriptor:texDesc];
|
||||
|
||||
if (texture==NULL) return NULL;
|
||||
FurnaceMetalTexture* ret=new FurnaceMetalTexture;
|
||||
ret->tex=texture;
|
||||
ret->width=width;
|
||||
ret->height=height;
|
||||
|
||||
[texDesc release];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderMetal::destroyTexture(FurnaceGUITexture* which) {
|
||||
FurnaceMetalTexture* t=(FurnaceMetalTexture*)which;
|
||||
[t->tex release];
|
||||
t->tex=NULL;
|
||||
delete t;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderMetal::setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode) {
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderMetal::setBlendMode(FurnaceGUIBlendMode mode) {
|
||||
}
|
||||
|
||||
// you should only call this once!!!
|
||||
void FurnaceGUIRenderMetal::clear(ImVec4 color) {
|
||||
int outW, outH;
|
||||
getOutputSize(outW,outH);
|
||||
priv->context.drawableSize=CGSizeMake(outW,outH);
|
||||
|
||||
if (priv->drawable) {
|
||||
[priv->drawable release];
|
||||
}
|
||||
if (priv->cmdBuf) {
|
||||
[priv->cmdBuf release];
|
||||
}
|
||||
|
||||
priv->drawable=[priv->context nextDrawable];
|
||||
|
||||
priv->cmdBuf=[priv->cmdQueue commandBuffer];
|
||||
priv->renderPass.colorAttachments[0].clearColor=MTLClearColorMake(color.x,color.y,color.z,color.w);
|
||||
priv->renderPass.colorAttachments[0].texture=priv->drawable.texture;
|
||||
priv->renderPass.colorAttachments[0].loadAction=MTLLoadActionClear;
|
||||
priv->renderPass.colorAttachments[0].storeAction=MTLStoreActionStore;
|
||||
priv->renderEncoder=[priv->cmdBuf renderCommandEncoderWithDescriptor:priv->renderPass];
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderMetal::newFrame() {
|
||||
return ImGui_ImplMetal_NewFrame(priv->renderPass);
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderMetal::canVSync() {
|
||||
return swapIntervalSet;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderMetal::createFontsTexture() {
|
||||
ImGui_ImplMetal_CreateFontsTexture(priv->context.device);
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderMetal::destroyFontsTexture() {
|
||||
ImGui_ImplMetal_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderMetal::renderGUI() {
|
||||
ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(),priv->cmdBuf,priv->renderEncoder);
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderMetal::wipe(float alpha) {
|
||||
// you know what? cheat.
|
||||
// I don't feel like learning yet another API just to please Apple.
|
||||
// screw it.
|
||||
SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(sdlRend,0,0,0,255*alpha);
|
||||
SDL_RenderFillRect(sdlRend,NULL);
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderMetal::present() {
|
||||
[priv->renderEncoder endEncoding];
|
||||
|
||||
[priv->cmdBuf presentDrawable:priv->drawable];
|
||||
[priv->cmdBuf commit];
|
||||
|
||||
[priv->renderEncoder release];
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderMetal::getOutputSize(int& w, int& h) {
|
||||
return SDL_GetRendererOutputSize(sdlRend,&w,&h)==0;
|
||||
}
|
||||
|
||||
int FurnaceGUIRenderMetal::getWindowFlags() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FurnaceGUIRenderMetal::getMaxTextureWidth() {
|
||||
return bigTextures?16384:8192;
|
||||
}
|
||||
|
||||
int FurnaceGUIRenderMetal::getMaxTextureHeight() {
|
||||
return bigTextures?16384:8192;
|
||||
}
|
||||
|
||||
unsigned int FurnaceGUIRenderMetal::getTextureFormats() {
|
||||
return GUI_TEXFORMAT_ABGR32;
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderMetal::getBackendName() {
|
||||
return "Metal";
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderMetal::getVendorName() {
|
||||
return vendorName.c_str();
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderMetal::getDeviceName() {
|
||||
return deviceName.c_str();
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderMetal::getAPIVersion() {
|
||||
return apiVersion.c_str();
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderMetal::setSwapInterval(int swapInterval) {
|
||||
if (SDL_RenderSetVSync(sdlRend,(swapInterval>=0)?1:0)!=0) {
|
||||
swapIntervalSet=false;
|
||||
logW("tried to enable VSync but couldn't!");
|
||||
} else {
|
||||
swapIntervalSet=true;
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderMetal::preInit(const DivConfig& conf) {
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER,"metal");
|
||||
priv=new FurnaceGUIRenderMetalPrivate;
|
||||
}
|
||||
|
||||
static const char* metalFamilyNames[]={
|
||||
"Apple1",
|
||||
"Apple2",
|
||||
"Apple3",
|
||||
"Apple4",
|
||||
"Apple5",
|
||||
"Apple6",
|
||||
"Apple7",
|
||||
"Apple8",
|
||||
"Apple9",
|
||||
"Mac1",
|
||||
"Mac2",
|
||||
"Common1",
|
||||
"Common2",
|
||||
"Common3",
|
||||
"Metal3",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const NSInteger metalFamilies[]={
|
||||
1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, // Apple
|
||||
2001, 2002, // Mac
|
||||
3001, 3002, 3003, // Common
|
||||
5001, // Metal3
|
||||
0
|
||||
};
|
||||
|
||||
bool FurnaceGUIRenderMetal::init(SDL_Window* win, int swapInterval) {
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER,"metal");
|
||||
|
||||
sdlRend=SDL_CreateRenderer(win,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC|SDL_RENDERER_TARGETTEXTURE);
|
||||
|
||||
if (sdlRend==NULL) return false;
|
||||
|
||||
if (SDL_RenderSetVSync(sdlRend,(swapInterval>=0)?1:0)!=0) {
|
||||
swapIntervalSet=false;
|
||||
logW("tried to enable VSync but couldn't!");
|
||||
} else {
|
||||
swapIntervalSet=true;
|
||||
}
|
||||
|
||||
logI("retrieving context...");
|
||||
|
||||
priv->context=(__bridge CAMetalLayer*)SDL_RenderGetMetalLayer(sdlRend);
|
||||
|
||||
if (priv->context==NULL) {
|
||||
logE("Metal layer is NULL!");
|
||||
return false;
|
||||
}
|
||||
|
||||
vendorName="N/A";
|
||||
deviceName=[priv->context.device.name UTF8String];
|
||||
apiVersion="";
|
||||
|
||||
bool comma=false;
|
||||
for (int i=0; metalFamilies[i]; i++) {
|
||||
const char* familyName=metalFamilyNames[i];
|
||||
MTLGPUFamily family=(MTLGPUFamily)metalFamilies[i];
|
||||
|
||||
if ([priv->context.device supportsFamily:family]) {
|
||||
if (comma) {
|
||||
apiVersion+=", ";
|
||||
}
|
||||
apiVersion+=familyName;
|
||||
comma=true;
|
||||
}
|
||||
}
|
||||
|
||||
priv->context.pixelFormat=MTLPixelFormatBGRA8Unorm;
|
||||
|
||||
priv->cmdQueue=[priv->context.device newCommandQueue];
|
||||
priv->renderPass=[MTLRenderPassDescriptor new];
|
||||
return true;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderMetal::initGUI(SDL_Window* win) {
|
||||
ImGui_ImplMetal_Init(priv->context.device);
|
||||
ImGui_ImplSDL2_InitForMetal(win);
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderMetal::quitGUI() {
|
||||
ImGui_ImplMetal_Shutdown();
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderMetal::quit() {
|
||||
if (sdlRend==NULL) return false;
|
||||
[priv->renderPass release];
|
||||
[priv->cmdQueue release];
|
||||
SDL_DestroyRenderer(sdlRend);
|
||||
sdlRend=NULL;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -24,8 +24,10 @@
|
|||
class FurnaceSDLTexture: public FurnaceGUITexture {
|
||||
public:
|
||||
SDL_Texture* tex;
|
||||
FurnaceGUITextureFormat format;
|
||||
FurnaceSDLTexture():
|
||||
tex(NULL) {}
|
||||
tex(NULL),
|
||||
format(GUI_TEXFORMAT_UNKNOWN) {}
|
||||
};
|
||||
|
||||
ImTextureID FurnaceGUIRenderSDL::getTextureID(FurnaceGUITexture* which) {
|
||||
|
|
@ -33,6 +35,11 @@ ImTextureID FurnaceGUIRenderSDL::getTextureID(FurnaceGUITexture* which) {
|
|||
return t->tex;
|
||||
}
|
||||
|
||||
FurnaceGUITextureFormat FurnaceGUIRenderSDL::getTextureFormat(FurnaceGUITexture* which) {
|
||||
FurnaceSDLTexture* t=(FurnaceSDLTexture*)which;
|
||||
return t->format;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSDL::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) {
|
||||
FurnaceSDLTexture* t=(FurnaceSDLTexture*)which;
|
||||
return SDL_LockTexture(t->tex,NULL,data,pitch)==0;
|
||||
|
|
@ -49,12 +56,19 @@ bool FurnaceGUIRenderSDL::updateTexture(FurnaceGUITexture* which, void* data, in
|
|||
return SDL_UpdateTexture(t->tex,NULL,data,pitch)==0;
|
||||
}
|
||||
|
||||
FurnaceGUITexture* FurnaceGUIRenderSDL::createTexture(bool dynamic, int width, int height) {
|
||||
FurnaceGUITexture* FurnaceGUIRenderSDL::createTexture(bool dynamic, int width, int height, bool interpolate, FurnaceGUITextureFormat format) {
|
||||
if (format!=GUI_TEXFORMAT_ABGR32) {
|
||||
logE("unsupported texture format!");
|
||||
return NULL;
|
||||
}
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,interpolate?"1":"0");
|
||||
SDL_Texture* t=SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ABGR8888,dynamic?SDL_TEXTUREACCESS_STREAMING:SDL_TEXTUREACCESS_STATIC,width,height);
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,"1");
|
||||
|
||||
if (t==NULL) return NULL;
|
||||
FurnaceSDLTexture* ret=new FurnaceSDLTexture;
|
||||
ret->tex=t;
|
||||
ret->format=format;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -110,6 +124,10 @@ bool FurnaceGUIRenderSDL::newFrame() {
|
|||
return ImGui_ImplSDLRenderer2_NewFrame();
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSDL::canVSync() {
|
||||
return swapIntervalSet;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSDL::createFontsTexture() {
|
||||
ImGui_ImplSDLRenderer2_CreateFontsTexture();
|
||||
}
|
||||
|
|
@ -140,12 +158,65 @@ int FurnaceGUIRenderSDL::getWindowFlags() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSDL::preInit() {
|
||||
int FurnaceGUIRenderSDL::getMaxTextureWidth() {
|
||||
if (!hasInfo) return 2048;
|
||||
return renderInfo.max_texture_width;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSDL::init(SDL_Window* win) {
|
||||
int FurnaceGUIRenderSDL::getMaxTextureHeight() {
|
||||
if (!hasInfo) return 2048;
|
||||
return renderInfo.max_texture_height;
|
||||
}
|
||||
|
||||
unsigned int FurnaceGUIRenderSDL::getTextureFormats() {
|
||||
return GUI_TEXFORMAT_ABGR32;
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderSDL::getBackendName() {
|
||||
return "SDL Renderer";
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderSDL::getVendorName() {
|
||||
return "SDL";
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderSDL::getDeviceName() {
|
||||
if (!hasInfo) return "???";
|
||||
return renderInfo.name;
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderSDL::getAPIVersion() {
|
||||
return "N/A";
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSDL::setSwapInterval(int swapInterval) {
|
||||
if (SDL_RenderSetVSync(sdlRend,(swapInterval>=0)?1:0)!=0) {
|
||||
swapIntervalSet=false;
|
||||
logW("tried to enable VSync but couldn't!");
|
||||
} else {
|
||||
swapIntervalSet=true;
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSDL::preInit(const DivConfig& conf) {
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSDL::init(SDL_Window* win, int swapInterval) {
|
||||
logV("creating SDL renderer...");
|
||||
sdlRend=SDL_CreateRenderer(win,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC|SDL_RENDERER_TARGETTEXTURE);
|
||||
sdlRend=SDL_CreateRenderer(win,-1,SDL_RENDERER_ACCELERATED|((swapInterval>0)?SDL_RENDERER_PRESENTVSYNC:0)|SDL_RENDERER_TARGETTEXTURE);
|
||||
if (sdlRend==NULL) return false;
|
||||
if (SDL_GetRendererInfo(sdlRend,&renderInfo)==0) {
|
||||
hasInfo=true;
|
||||
} else {
|
||||
logE("could not get renderer info! %s",SDL_GetError());
|
||||
hasInfo=false;
|
||||
}
|
||||
if (SDL_RenderSetVSync(sdlRend,(swapInterval>=0)?1:0)!=0) {
|
||||
swapIntervalSet=false;
|
||||
logW("tried to enable VSync but couldn't!");
|
||||
} else {
|
||||
swapIntervalSet=true;
|
||||
}
|
||||
logV("(post creation)");
|
||||
return (sdlRend!=NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,17 +21,22 @@
|
|||
|
||||
class FurnaceGUIRenderSDL: public FurnaceGUIRender {
|
||||
SDL_Renderer* sdlRend;
|
||||
SDL_RendererInfo renderInfo;
|
||||
bool hasInfo;
|
||||
bool swapIntervalSet;
|
||||
public:
|
||||
ImTextureID getTextureID(FurnaceGUITexture* which);
|
||||
FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which);
|
||||
bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
|
||||
bool unlockTexture(FurnaceGUITexture* which);
|
||||
bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
|
||||
FurnaceGUITexture* createTexture(bool dynamic, int width, int height);
|
||||
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true, FurnaceGUITextureFormat format=GUI_TEXFORMAT_ABGR32);
|
||||
bool destroyTexture(FurnaceGUITexture* which);
|
||||
void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
|
||||
void setBlendMode(FurnaceGUIBlendMode mode);
|
||||
void clear(ImVec4 color);
|
||||
bool newFrame();
|
||||
bool canVSync();
|
||||
void createFontsTexture();
|
||||
void destroyFontsTexture();
|
||||
void renderGUI();
|
||||
|
|
@ -39,11 +44,21 @@ class FurnaceGUIRenderSDL: public FurnaceGUIRender {
|
|||
void present();
|
||||
bool getOutputSize(int& w, int& h);
|
||||
int getWindowFlags();
|
||||
void preInit();
|
||||
bool init(SDL_Window* win);
|
||||
int getMaxTextureWidth();
|
||||
int getMaxTextureHeight();
|
||||
unsigned int getTextureFormats();
|
||||
const char* getBackendName();
|
||||
const char* getVendorName();
|
||||
const char* getDeviceName();
|
||||
const char* getAPIVersion();
|
||||
void setSwapInterval(int swapInterval);
|
||||
void preInit(const DivConfig& conf);
|
||||
bool init(SDL_Window* win, int swapInterval);
|
||||
void initGUI(SDL_Window* win);
|
||||
void quitGUI();
|
||||
bool quit();
|
||||
FurnaceGUIRenderSDL():
|
||||
sdlRend(NULL) {}
|
||||
};
|
||||
sdlRend(NULL),
|
||||
hasInfo(false),
|
||||
swapIntervalSet(true) {}
|
||||
};
|
||||
|
|
|
|||
199
src/gui/render/renderSoftware.cpp
Normal file
199
src/gui/render/renderSoftware.cpp
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2024 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 "renderSoftware.h"
|
||||
#include "imgui_sw.hpp"
|
||||
#include "../../ta-log.h"
|
||||
|
||||
class FurnaceSoftwareTexture: public FurnaceGUITexture {
|
||||
public:
|
||||
SWTexture* tex;
|
||||
FurnaceGUITextureFormat format;
|
||||
FurnaceSoftwareTexture():
|
||||
tex(NULL),
|
||||
format(GUI_TEXFORMAT_UNKNOWN) {}
|
||||
};
|
||||
|
||||
ImTextureID FurnaceGUIRenderSoftware::getTextureID(FurnaceGUITexture* which) {
|
||||
FurnaceSoftwareTexture* t=(FurnaceSoftwareTexture*)which;
|
||||
return t->tex;
|
||||
}
|
||||
|
||||
FurnaceGUITextureFormat FurnaceGUIRenderSoftware::getTextureFormat(FurnaceGUITexture* which) {
|
||||
FurnaceSoftwareTexture* t=(FurnaceSoftwareTexture*)which;
|
||||
return t->format;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSoftware::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) {
|
||||
FurnaceSoftwareTexture* t=(FurnaceSoftwareTexture*)which;
|
||||
if (!t->tex->managed) return false;
|
||||
*data=t->tex->pixels;
|
||||
*pitch=t->tex->width*(t->tex->isAlpha?1:4);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSoftware::unlockTexture(FurnaceGUITexture* which) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSoftware::updateTexture(FurnaceGUITexture* which, void* data, int pitch) {
|
||||
FurnaceSoftwareTexture* t=(FurnaceSoftwareTexture*)which;
|
||||
if (!t->tex->managed) return false;
|
||||
memcpy(t->tex->pixels,data,pitch*t->tex->height);
|
||||
return true;
|
||||
}
|
||||
|
||||
FurnaceGUITexture* FurnaceGUIRenderSoftware::createTexture(bool dynamic, int width, int height, bool interpolate, FurnaceGUITextureFormat format) {
|
||||
if (format!=GUI_TEXFORMAT_ARGB32) {
|
||||
logE("unsupported texture format!");
|
||||
return NULL;
|
||||
}
|
||||
FurnaceSoftwareTexture* ret=new FurnaceSoftwareTexture;
|
||||
ret->tex=new SWTexture(width,height);
|
||||
ret->format=format;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSoftware::destroyTexture(FurnaceGUITexture* which) {
|
||||
FurnaceSoftwareTexture* t=(FurnaceSoftwareTexture*)which;
|
||||
|
||||
delete t->tex;
|
||||
delete t;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSoftware::setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSoftware::setBlendMode(FurnaceGUIBlendMode mode) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSoftware::clear(ImVec4 color) {
|
||||
SDL_Surface* surf=SDL_GetWindowSurface(sdlWin);
|
||||
if (!surf) return;
|
||||
ImU32 clearToWhat=ImGui::ColorConvertFloat4ToU32(color);
|
||||
clearToWhat=(clearToWhat&0xff00ff00)|((clearToWhat&0xff)<<16)|((clearToWhat&0xff0000)>>16);
|
||||
|
||||
bool mustLock=SDL_MUSTLOCK(surf);
|
||||
if (mustLock) {
|
||||
if (SDL_LockSurface(surf)!=0) return;
|
||||
}
|
||||
unsigned int* pixels=(unsigned int*)surf->pixels;
|
||||
for (size_t total=surf->w*surf->h; total; total--) {
|
||||
*(pixels++)=clearToWhat;
|
||||
}
|
||||
if (mustLock) {
|
||||
SDL_UnlockSurface(surf);
|
||||
}
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSoftware::newFrame() {
|
||||
return ImGui_ImplSW_NewFrame();
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSoftware::canVSync() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSoftware::createFontsTexture() {
|
||||
ImGui_ImplSW_CreateFontsTexture();
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSoftware::destroyFontsTexture() {
|
||||
ImGui_ImplSW_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSoftware::renderGUI() {
|
||||
ImGui_ImplSW_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSoftware::wipe(float alpha) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSoftware::present() {
|
||||
SDL_UpdateWindowSurface(sdlWin);
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSoftware::getOutputSize(int& w, int& h) {
|
||||
SDL_Surface* surf=SDL_GetWindowSurface(sdlWin);
|
||||
if (surf==NULL) return false;
|
||||
w=surf->w;
|
||||
h=surf->h;
|
||||
return true;
|
||||
}
|
||||
|
||||
int FurnaceGUIRenderSoftware::getWindowFlags() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FurnaceGUIRenderSoftware::getMaxTextureWidth() {
|
||||
return 16384;
|
||||
}
|
||||
|
||||
int FurnaceGUIRenderSoftware::getMaxTextureHeight() {
|
||||
return 16384;
|
||||
}
|
||||
|
||||
unsigned int FurnaceGUIRenderSoftware::getTextureFormats() {
|
||||
return GUI_TEXFORMAT_ARGB32;
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderSoftware::getBackendName() {
|
||||
return "Software";
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderSoftware::getVendorName() {
|
||||
return "emilk, JesusKrists and tildearrow";
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderSoftware::getDeviceName() {
|
||||
return "imgui_sw Software Renderer";
|
||||
}
|
||||
|
||||
const char* FurnaceGUIRenderSoftware::getAPIVersion() {
|
||||
return "N/A";
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSoftware::setSwapInterval(int swapInterval) {
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSoftware::preInit(const DivConfig& conf) {
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSoftware::init(SDL_Window* win, int swapInterval) {
|
||||
sdlWin=win;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSoftware::initGUI(SDL_Window* win) {
|
||||
// hack
|
||||
ImGui_ImplSDL2_InitForMetal(win);
|
||||
ImGui_ImplSW_Init(win);
|
||||
}
|
||||
|
||||
void FurnaceGUIRenderSoftware::quitGUI() {
|
||||
ImGui_ImplSW_Shutdown();
|
||||
}
|
||||
|
||||
bool FurnaceGUIRenderSoftware::quit() {
|
||||
return true;
|
||||
}
|
||||
59
src/gui/render/renderSoftware.h
Normal file
59
src/gui/render/renderSoftware.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2024 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"
|
||||
|
||||
class FurnaceGUIRenderSoftware: public FurnaceGUIRender {
|
||||
SDL_Window* sdlWin;
|
||||
public:
|
||||
ImTextureID getTextureID(FurnaceGUITexture* which);
|
||||
FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which);
|
||||
bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
|
||||
bool unlockTexture(FurnaceGUITexture* which);
|
||||
bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
|
||||
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true, FurnaceGUITextureFormat format=GUI_TEXFORMAT_ABGR32);
|
||||
bool destroyTexture(FurnaceGUITexture* which);
|
||||
void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
|
||||
void setBlendMode(FurnaceGUIBlendMode mode);
|
||||
void clear(ImVec4 color);
|
||||
bool newFrame();
|
||||
bool canVSync();
|
||||
void createFontsTexture();
|
||||
void destroyFontsTexture();
|
||||
void renderGUI();
|
||||
void wipe(float alpha);
|
||||
void present();
|
||||
bool getOutputSize(int& w, int& h);
|
||||
int getWindowFlags();
|
||||
int getMaxTextureWidth();
|
||||
int getMaxTextureHeight();
|
||||
unsigned int getTextureFormats();
|
||||
const char* getBackendName();
|
||||
const char* getVendorName();
|
||||
const char* getDeviceName();
|
||||
const char* getAPIVersion();
|
||||
void setSwapInterval(int swapInterval);
|
||||
void preInit(const DivConfig& conf);
|
||||
bool init(SDL_Window* win, int swapInterval);
|
||||
void initGUI(SDL_Window* win);
|
||||
void quitGUI();
|
||||
bool quit();
|
||||
FurnaceGUIRenderSoftware():
|
||||
sdlWin(NULL) {}
|
||||
};
|
||||
|
|
@ -31,6 +31,15 @@
|
|||
#include "sampleUtil.h"
|
||||
#include "util.h"
|
||||
|
||||
#define SWAP_COLOR_ARGB(x) \
|
||||
x=(x&0xff00ff00)|((x&0xff)<<16)|((x&0xff0000)>>16);
|
||||
|
||||
#define SWAP_COLOR_BGRA(x) \
|
||||
x=((x&0xff0000000)>>24)|((x&0xffffff)<<8);
|
||||
|
||||
#define SWAP_COLOR_RGBA(x) \
|
||||
x=((x&0xff)<<24)|((x&0xff00)<<8)|((x&0xff0000)>>8)|((x&0xff000000)>>24);
|
||||
|
||||
const double timeDivisors[10]={
|
||||
1000.0, 500.0, 200.0, 100.0, 50.0, 20.0, 10.0, 5.0, 2.0, 1.0
|
||||
};
|
||||
|
|
@ -53,21 +62,21 @@ const double timeMultipliers[13]={
|
|||
#define MAX_RATE(_name,_x) \
|
||||
if (e->isPreviewingSample()) { \
|
||||
if ((int)e->getSamplePreviewRate()>(int)(_x)) { \
|
||||
SAMPLE_WARN(warnRate,fmt::sprintf("%s: maximum sample rate is %d",_name,(int)(_x))); \
|
||||
SAMPLE_WARN(warnRate,fmt::sprintf(_("%s: maximum sample rate is %d"),_name,(int)(_x))); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define MIN_RATE(_name,_x) \
|
||||
if (e->isPreviewingSample()) { \
|
||||
if ((int)e->getSamplePreviewRate()<(int)(_x)) { \
|
||||
SAMPLE_WARN(warnRate,fmt::sprintf("%s: minimum sample rate is %d",_name,(int)(_x))); \
|
||||
SAMPLE_WARN(warnRate,fmt::sprintf(_("%s: minimum sample rate is %d"),_name,(int)(_x))); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define EXACT_RATE(_name,_x) \
|
||||
if (e->isPreviewingSample()) { \
|
||||
if ((int)e->getSamplePreviewRate()!=(int)(_x)) { \
|
||||
SAMPLE_WARN(warnRate,fmt::sprintf("%s: sample rate must be %d",_name,(int)(_x))); \
|
||||
SAMPLE_WARN(warnRate,fmt::sprintf(_("%s: sample rate must be %d"),_name,(int)(_x))); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
|
@ -84,11 +93,11 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
ImGui::SetNextWindowPos(patWindowPos);
|
||||
ImGui::SetNextWindowSize(patWindowSize);
|
||||
}
|
||||
if (ImGui::Begin("Sample Editor",&sampleEditOpen,globalWinFlags|(settings.allowEditDocking?0:ImGuiWindowFlags_NoDocking))) {
|
||||
if (ImGui::Begin("Sample Editor",&sampleEditOpen,globalWinFlags|(settings.allowEditDocking?0:ImGuiWindowFlags_NoDocking),_("Sample Editor"))) {
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) {
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY()+(ImGui::GetContentRegionAvail().y-ImGui::GetFrameHeightWithSpacing()*2.0f)*0.5f);
|
||||
CENTER_TEXT("no sample selected");
|
||||
ImGui::Text("no sample selected");
|
||||
CENTER_TEXT(_("no sample selected"));
|
||||
ImGui::Text(_("no sample selected"));
|
||||
if (ImGui::BeginTable("noAssetCenter",3)) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.5f);
|
||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed);
|
||||
|
|
@ -99,7 +108,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
ImGui::TableNextColumn();
|
||||
|
||||
if (e->song.sample.size()>0) {
|
||||
if (ImGui::BeginCombo("##SampleSelect","select one...")) {
|
||||
if (ImGui::BeginCombo("##SampleSelect",_("select one..."))) {
|
||||
if (ImGui::BeginTable("SampleSelCombo",1,ImGuiTableFlags_ScrollY)) {
|
||||
actualSampleList();
|
||||
ImGui::EndTable();
|
||||
|
|
@ -107,16 +116,16 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::TextUnformatted("or");
|
||||
ImGui::TextUnformatted(_("or"));
|
||||
ImGui::SameLine();
|
||||
}
|
||||
if (ImGui::Button("Open")) {
|
||||
if (ImGui::Button(_("Open"))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_OPEN);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::TextUnformatted("or");
|
||||
ImGui::TextUnformatted(_("or"));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Create New")) {
|
||||
if (ImGui::Button(_("Create New"))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_ADD);
|
||||
}
|
||||
|
||||
|
|
@ -125,16 +134,16 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
}
|
||||
} else {
|
||||
DivSample* sample=e->song.sample[curSample];
|
||||
String sampleType="Invalid";
|
||||
String sampleType=_("Invalid");
|
||||
if (sample->depth<DIV_SAMPLE_DEPTH_MAX) {
|
||||
if (sampleDepths[sample->depth]!=NULL) {
|
||||
sampleType=sampleDepths[sample->depth];
|
||||
}
|
||||
}
|
||||
String loopType="Invalid";
|
||||
String loopType=_("Invalid");
|
||||
if (sample->loopMode<DIV_SAMPLE_LOOP_MAX) {
|
||||
if (sampleLoopModes[sample->loopMode]!=NULL) {
|
||||
loopType=sampleLoopModes[sample->loopMode];
|
||||
loopType=_(sampleLoopModes[sample->loopMode]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,10 +168,10 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
doAction(GUI_ACTION_SAMPLE_LIST_OPEN_REPLACE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Open");
|
||||
ImGui::SetTooltip(_("Open"));
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("SampleEOpenOpt")) {
|
||||
if (ImGui::MenuItem("import raw...")) {
|
||||
if (ImGui::MenuItem(_("import raw..."))) {
|
||||
doAction((curSample>=0 && curSample<(int)e->song.sample.size())?GUI_ACTION_SAMPLE_LIST_OPEN_REPLACE_RAW:GUI_ACTION_SAMPLE_LIST_OPEN_RAW);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
|
|
@ -172,10 +181,10 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
doAction(GUI_ACTION_SAMPLE_LIST_SAVE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Save");
|
||||
ImGui::SetTooltip(_("Save"));
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("SampleESaveOpt")) {
|
||||
if (ImGui::MenuItem("save raw...")) {
|
||||
if (ImGui::MenuItem(_("save raw..."))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_SAVE_RAW);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
|
|
@ -183,7 +192,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::Text("Name");
|
||||
ImGui::Text(_("Name"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::PushID(2+curSample);
|
||||
|
|
@ -217,18 +226,18 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
if (sample->loopStart&15) {
|
||||
int tryWith=(sample->loopStart+8)&(~15);
|
||||
if (tryWith>(int)sample->samples) tryWith-=16;
|
||||
String alignHint=fmt::sprintf("SNES: loop start must be a multiple of 16 (try with %d)",tryWith);
|
||||
String alignHint=fmt::sprintf(_("SNES: loop start must be a multiple of 16 (try with %d)"),tryWith);
|
||||
SAMPLE_WARN(warnLoopStart,alignHint);
|
||||
}
|
||||
if (sample->loopEnd&15) {
|
||||
int tryWith=(sample->loopEnd+8)&(~15);
|
||||
if (tryWith>(int)sample->samples) tryWith-=16;
|
||||
String alignHint=fmt::sprintf("SNES: loop end must be a multiple of 16 (try with %d)",tryWith);
|
||||
String alignHint=fmt::sprintf(_("SNES: loop end must be a multiple of 16 (try with %d)"),tryWith);
|
||||
SAMPLE_WARN(warnLoopEnd,alignHint);
|
||||
}
|
||||
}
|
||||
if (sample->samples&15) {
|
||||
SAMPLE_WARN(warnLength,"SNES: sample length will be padded to multiple of 16");
|
||||
SAMPLE_WARN(warnLength,_("SNES: sample length will be padded to multiple of 16"));
|
||||
}
|
||||
if (dispatch!=NULL) {
|
||||
MAX_RATE("SNES",dispatch->chipClock/8.0);
|
||||
|
|
@ -237,7 +246,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
case DIV_SYSTEM_QSOUND:
|
||||
if (sample->loop) {
|
||||
if (sample->loopEnd-sample->loopStart>32767) {
|
||||
SAMPLE_WARN(warnLoopPos,"QSound: loop cannot be longer than 32767 samples");
|
||||
SAMPLE_WARN(warnLoopPos,_("QSound: loop cannot be longer than 32767 samples"));
|
||||
}
|
||||
}
|
||||
if (sample->samples>65535) {
|
||||
|
|
@ -247,24 +256,24 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
case DIV_SYSTEM_NES:
|
||||
if (sample->loop) {
|
||||
if (sample->loopStart!=0 || sample->loopEnd!=(int)(sample->samples)) {
|
||||
SAMPLE_WARN(warnLoopPos,"NES: loop point ignored on DPCM (may only loop entire sample)");
|
||||
SAMPLE_WARN(warnLoopPos,_("NES: loop point ignored on DPCM (may only loop entire sample)"));
|
||||
}
|
||||
}
|
||||
if (sample->samples>32648) {
|
||||
SAMPLE_WARN(warnLength,"NES: maximum DPCM sample length is 32648");
|
||||
SAMPLE_WARN(warnLength,_("NES: maximum DPCM sample length is 32648"));
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_X1_010:
|
||||
if (sample->loop) {
|
||||
SAMPLE_WARN(warnLoop,"X1-010: samples can't loop");
|
||||
SAMPLE_WARN(warnLoop,_("X1-010: samples can't loop"));
|
||||
}
|
||||
if (sample->samples>131072) {
|
||||
SAMPLE_WARN(warnLength,"X1-010: maximum sample length is 131072");
|
||||
SAMPLE_WARN(warnLength,_("X1-010: maximum sample length is 131072"));
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_GA20:
|
||||
if (sample->loop) {
|
||||
SAMPLE_WARN(warnLoop,"GA20: samples can't loop");
|
||||
SAMPLE_WARN(warnLoop,_("GA20: samples can't loop"));
|
||||
}
|
||||
if (dispatch!=NULL) {
|
||||
MIN_RATE("GA20",dispatch->chipClock/1024);
|
||||
|
|
@ -275,10 +284,10 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
case DIV_SYSTEM_YM2608_CSM:
|
||||
if (sample->loop) {
|
||||
if (sample->loopStart!=0 || sample->loopEnd!=(int)(sample->samples)) {
|
||||
SAMPLE_WARN(warnLoopPos,"YM2608: loop point ignored on ADPCM (may only loop entire sample)");
|
||||
SAMPLE_WARN(warnLoopPos,_("YM2608: loop point ignored on ADPCM (may only loop entire sample)"));
|
||||
}
|
||||
if (sample->samples&511) {
|
||||
SAMPLE_WARN(warnLength,"YM2608: sample length will be padded to multiple of 512");
|
||||
SAMPLE_WARN(warnLength,_("YM2608: sample length will be padded to multiple of 512"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -288,16 +297,16 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
case DIV_SYSTEM_YM2610B:
|
||||
case DIV_SYSTEM_YM2610B_EXT:
|
||||
if (sample->loop) {
|
||||
SAMPLE_WARN(warnLoop,"YM2610: ADPCM-A samples can't loop");
|
||||
SAMPLE_WARN(warnLoop,_("YM2610: ADPCM-A samples can't loop"));
|
||||
if (sample->loopStart!=0 || sample->loopEnd!=(int)(sample->samples)) {
|
||||
SAMPLE_WARN(warnLoopPos,"YM2610: loop point ignored on ADPCM-B (may only loop entire sample)");
|
||||
SAMPLE_WARN(warnLoopPos,_("YM2610: loop point ignored on ADPCM-B (may only loop entire sample)"));
|
||||
}
|
||||
if (sample->samples&511) {
|
||||
SAMPLE_WARN(warnLength,"YM2610: sample length will be padded to multiple of 512");
|
||||
SAMPLE_WARN(warnLength,_("YM2610: sample length will be padded to multiple of 512"));
|
||||
}
|
||||
}
|
||||
if (sample->samples>2097152) {
|
||||
SAMPLE_WARN(warnLength,"YM2610: maximum ADPCM-A sample length is 2097152");
|
||||
SAMPLE_WARN(warnLength,_("YM2610: maximum ADPCM-A sample length is 2097152"));
|
||||
}
|
||||
if (dispatch!=NULL) {
|
||||
EXACT_RATE("YM2610 (ADPCM-A)",dispatch->chipClock/432);
|
||||
|
|
@ -306,24 +315,24 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
case DIV_SYSTEM_Y8950:
|
||||
if (sample->loop) {
|
||||
if (sample->loopStart!=0 || sample->loopEnd!=(int)(sample->samples)) {
|
||||
SAMPLE_WARN(warnLoopPos,"Y8950: loop point ignored on ADPCM (may only loop entire sample)");
|
||||
SAMPLE_WARN(warnLoopPos,_("Y8950: loop point ignored on ADPCM (may only loop entire sample)"));
|
||||
}
|
||||
if (sample->samples&511) {
|
||||
SAMPLE_WARN(warnLength,"Y8950: sample length will be padded to multiple of 512");
|
||||
SAMPLE_WARN(warnLength,_("Y8950: sample length will be padded to multiple of 512"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_AMIGA:
|
||||
if (sample->loop) {
|
||||
if (sample->loopStart&1) {
|
||||
SAMPLE_WARN(warnLoopStart,"Amiga: loop start must be a multiple of 2");
|
||||
SAMPLE_WARN(warnLoopStart,_("Amiga: loop start must be a multiple of 2"));
|
||||
}
|
||||
if (sample->loopEnd&1) {
|
||||
SAMPLE_WARN(warnLoopEnd,"Amiga: loop end must be a multiple of 2");
|
||||
SAMPLE_WARN(warnLoopEnd,_("Amiga: loop end must be a multiple of 2"));
|
||||
}
|
||||
}
|
||||
if (sample->samples>131070) {
|
||||
SAMPLE_WARN(warnLength,"Amiga: maximum sample length is 131070");
|
||||
SAMPLE_WARN(warnLength,_("Amiga: maximum sample length is 131070"));
|
||||
}
|
||||
if (dispatch!=NULL) {
|
||||
MAX_RATE("Amiga",31250.0);
|
||||
|
|
@ -332,7 +341,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
case DIV_SYSTEM_SEGAPCM:
|
||||
case DIV_SYSTEM_SEGAPCM_COMPAT:
|
||||
if (sample->samples>65280) {
|
||||
SAMPLE_WARN(warnLength,"SegaPCM: maximum sample length is 65280");
|
||||
SAMPLE_WARN(warnLength,_("SegaPCM: maximum sample length is 65280"));
|
||||
}
|
||||
if (dispatch!=NULL) {
|
||||
MAX_RATE("SegaPCM",dispatch->chipClock/256);
|
||||
|
|
@ -341,16 +350,16 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
case DIV_SYSTEM_K053260:
|
||||
if (sample->loop) {
|
||||
if (sample->loopStart!=0 || sample->loopEnd!=(int)(sample->samples)) {
|
||||
SAMPLE_WARN(warnLoopPos,"K053260: loop point ignored (may only loop entire sample)");
|
||||
SAMPLE_WARN(warnLoopPos,_("K053260: loop point ignored (may only loop entire sample)"));
|
||||
}
|
||||
}
|
||||
if (sample->samples>65535) {
|
||||
SAMPLE_WARN(warnLength,"K053260: maximum sample length is 65535");
|
||||
SAMPLE_WARN(warnLength,_("K053260: maximum sample length is 65535"));
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_C140:
|
||||
if (sample->samples>65535) {
|
||||
SAMPLE_WARN(warnLength,"C140: maximum sample length is 65535");
|
||||
SAMPLE_WARN(warnLength,_("C140: maximum sample length is 65535"));
|
||||
}
|
||||
if (dispatch!=NULL) {
|
||||
MAX_RATE("C140",dispatch->rate);
|
||||
|
|
@ -359,14 +368,14 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
case DIV_SYSTEM_C219:
|
||||
if (sample->loop) {
|
||||
if (sample->loopStart&1) {
|
||||
SAMPLE_WARN(warnLoopStart,"C219: loop start must be a multiple of 2");
|
||||
SAMPLE_WARN(warnLoopStart,_("C219: loop start must be a multiple of 2"));
|
||||
}
|
||||
if (sample->loopEnd&1) {
|
||||
SAMPLE_WARN(warnLoopEnd,"C219: loop end must be a multiple of 2");
|
||||
SAMPLE_WARN(warnLoopEnd,_("C219: loop end must be a multiple of 2"));
|
||||
}
|
||||
}
|
||||
if (sample->samples>131072) {
|
||||
SAMPLE_WARN(warnLength,"C219: maximum sample length is 131072");
|
||||
SAMPLE_WARN(warnLength,_("C219: maximum sample length is 131072"));
|
||||
}
|
||||
if (dispatch!=NULL) {
|
||||
MAX_RATE("C219",dispatch->rate);
|
||||
|
|
@ -374,23 +383,23 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
break;
|
||||
case DIV_SYSTEM_MSM6295:
|
||||
if (sample->loop) {
|
||||
SAMPLE_WARN(warnLoop,"MSM6295: samples can't loop");
|
||||
SAMPLE_WARN(warnLoop,_("MSM6295: samples can't loop"));
|
||||
}
|
||||
if (sample->samples>129024) {
|
||||
SAMPLE_WARN(warnLength,"MSM6295: maximum bankswitched sample length is 129024");
|
||||
SAMPLE_WARN(warnLength,_("MSM6295: maximum bankswitched sample length is 129024"));
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_GBA_DMA:
|
||||
if (sample->loop) {
|
||||
if (sample->loopStart&3) {
|
||||
SAMPLE_WARN(warnLoopStart,"GBA DMA: loop start must be a multiple of 4");
|
||||
SAMPLE_WARN(warnLoopStart,_("GBA DMA: loop start must be a multiple of 4"));
|
||||
}
|
||||
if ((sample->loopEnd-sample->loopStart)&15) {
|
||||
SAMPLE_WARN(warnLoopEnd,"GBA DMA: loop length must be a multiple of 16");
|
||||
SAMPLE_WARN(warnLoopEnd,_("GBA DMA: loop length must be a multiple of 16"));
|
||||
}
|
||||
}
|
||||
if (sample->samples&15) {
|
||||
SAMPLE_WARN(warnLength,"GBA DMA: sample length will be padded to multiple of 16");
|
||||
SAMPLE_WARN(warnLength,_("GBA DMA: sample length will be padded to multiple of 16"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -399,10 +408,10 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
if (e->song.system[i]!=DIV_SYSTEM_PCM_DAC) {
|
||||
if (e->song.system[i]==DIV_SYSTEM_ES5506) {
|
||||
if (sample->loopMode==DIV_SAMPLE_LOOP_BACKWARD) {
|
||||
SAMPLE_WARN(warnLoopMode,"ES5506: backward loop mode isn't supported");
|
||||
SAMPLE_WARN(warnLoopMode,_("ES5506: backward loop mode isn't supported"));
|
||||
}
|
||||
} else if (sample->loopMode!=DIV_SAMPLE_LOOP_FORWARD) {
|
||||
SAMPLE_WARN(warnLoopMode,"backward/ping-pong only supported in Generic PCM DAC\nping-pong also on ES5506");
|
||||
SAMPLE_WARN(warnLoopMode,_("backward/ping-pong only supported in Generic PCM DAC\nping-pong also on ES5506"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -432,26 +441,26 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
sampleInfo=!sampleInfo;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("Info");
|
||||
ImGui::Text(_("Info"));
|
||||
ImGui::TableNextColumn();
|
||||
pushToggleColors(!sampleCompatRate);
|
||||
if (ImGui::Button("Rate")) {
|
||||
if (ImGui::Button(_("Rate"))) {
|
||||
sampleCompatRate=false;
|
||||
}
|
||||
popToggleColors();
|
||||
ImGui::SameLine();
|
||||
pushToggleColors(sampleCompatRate);
|
||||
if (ImGui::Button("Compat Rate")) {
|
||||
if (ImGui::Button(_("Compat Rate"))) {
|
||||
sampleCompatRate=true;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("used in DefleMask-compatible sample mode (17xx), in where samples are mapped to an octave.");
|
||||
ImGui::SetTooltip(_("used in DefleMask-compatible sample mode (17xx), in where samples are mapped to an octave."));
|
||||
}
|
||||
popToggleColors();
|
||||
ImGui::TableNextColumn();
|
||||
bool doLoop=(sample->loop);
|
||||
pushWarningColor(!warnLoop.empty());
|
||||
String loopCheckboxName=(doLoop && (sample->loopEnd-sample->loopStart)>0)?fmt::sprintf("Loop (length: %d)##Loop",sample->loopEnd-sample->loopStart):String("Loop");
|
||||
String loopCheckboxName=(doLoop && (sample->loopEnd-sample->loopStart)>0)?fmt::sprintf(_("Loop (length: %d)##Loop"),sample->loopEnd-sample->loopStart):String(_("Loop"));
|
||||
if (ImGui::Checkbox(loopCheckboxName.c_str(),&doLoop)) { MARK_MODIFIED
|
||||
if (doLoop) {
|
||||
sample->loop=true;
|
||||
|
|
@ -475,21 +484,21 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
popWarningColor();
|
||||
if (ImGui::IsItemHovered() && (!warnLoop.empty() || sample->depth==DIV_SAMPLE_DEPTH_BRR)) {
|
||||
if (sample->depth==DIV_SAMPLE_DEPTH_BRR) {
|
||||
SAMPLE_WARN(warnLoop,"changing the loop in a BRR sample may result in glitches!");
|
||||
SAMPLE_WARN(warnLoop,_("changing the loop in a BRR sample may result in glitches!"));
|
||||
}
|
||||
ImGui::SetTooltip("%s",warnLoop.c_str());
|
||||
}
|
||||
|
||||
if (selColumns>1) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Chips");
|
||||
ImGui::Text(_("Chips"));
|
||||
}
|
||||
|
||||
if (sampleInfo) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Type");
|
||||
ImGui::Text(_("Type"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::BeginCombo("##SampleType",sampleType.c_str())) {
|
||||
|
|
@ -498,7 +507,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
if (ImGui::Selectable(sampleDepths[i])) {
|
||||
sample->prepareUndo(true);
|
||||
e->lockEngine([this,sample,i]() {
|
||||
sample->convert((DivSampleDepth)i);
|
||||
sample->convert((DivSampleDepth)i,e->getSampleFormatMask());
|
||||
e->renderSamples(curSample);
|
||||
});
|
||||
updateSampleTex=true;
|
||||
|
|
@ -517,7 +526,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
}
|
||||
if (sample->depth==DIV_SAMPLE_DEPTH_BRR || isThereSNES) {
|
||||
bool be=sample->brrEmphasis;
|
||||
if (ImGui::Checkbox("BRR emphasis",&be)) {
|
||||
if (ImGui::Checkbox(_("BRR emphasis"),&be)) {
|
||||
sample->prepareUndo(true);
|
||||
sample->brrEmphasis=be;
|
||||
e->renderSamplesP(curSample);
|
||||
|
|
@ -526,15 +535,28 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
if (sample->depth==DIV_SAMPLE_DEPTH_BRR) {
|
||||
ImGui::SetTooltip("this is a BRR sample.\nenabling this option will muffle it (only affects non-SNES chips).");
|
||||
ImGui::SetTooltip(_("this is a BRR sample.\nenabling this option will muffle it (only affects non-SNES chips)."));
|
||||
} else {
|
||||
ImGui::SetTooltip("enable this option to slightly boost high frequencies\nto compensate for the SNES' Gaussian filter's muffle.");
|
||||
ImGui::SetTooltip(_("enable this option to slightly boost high frequencies\nto compensate for the SNES' Gaussian filter's muffle."));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sample->depth!=DIV_SAMPLE_DEPTH_BRR && isThereSNES) {
|
||||
bool bf=sample->brrNoFilter;
|
||||
if (ImGui::Checkbox(_("no BRR filters"),&bf)) {
|
||||
sample->prepareUndo(true);
|
||||
sample->brrNoFilter=bf;
|
||||
e->renderSamplesP(curSample);
|
||||
updateSampleTex=true;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip(_("enable this option to not use BRR blocks with filters\nand allow sample offset commands to be used safely."));
|
||||
}
|
||||
}
|
||||
if (sample->depth!=DIV_SAMPLE_DEPTH_8BIT && e->getSampleFormatMask()&(1L<<DIV_SAMPLE_DEPTH_8BIT)) {
|
||||
bool di=sample->dither;
|
||||
if (ImGui::Checkbox("8-bit dither",&di)) {
|
||||
if (ImGui::Checkbox(_("8-bit dither"),&di)) {
|
||||
sample->prepareUndo(true);
|
||||
sample->dither=di;
|
||||
e->renderSamplesP(curSample);
|
||||
|
|
@ -542,7 +564,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
MARK_MODIFIED;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("dither the sample when used on a chip that only supports 8-bit samples.");
|
||||
ImGui::SetTooltip(_("dither the sample when used on a chip that only supports 8-bit samples."));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -578,7 +600,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
}
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Note");
|
||||
ImGui::Text(_("Note"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::BeginCombo("##SampleNote",noteNames[sampleNoteCoarse+60])) {
|
||||
|
|
@ -683,7 +705,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
|
||||
pushWarningColor(!warnLoopPos.empty() || !warnLoopStart.empty());
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Start");
|
||||
ImGui::Text(_("Start"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputInt("##LoopStartPosition",&sample->loopStart,1,16)) { MARK_MODIFIED
|
||||
|
|
@ -704,7 +726,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
if (ImGui::IsItemHovered() && (!warnLoopPos.empty() || !warnLoopStart.empty() || sample->depth==DIV_SAMPLE_DEPTH_BRR)) {
|
||||
if (ImGui::BeginTooltip()) {
|
||||
if (sample->depth==DIV_SAMPLE_DEPTH_BRR) {
|
||||
ImGui::Text("changing the loop in a BRR sample may result in glitches!");
|
||||
ImGui::Text(_("changing the loop in a BRR sample may result in glitches!"));
|
||||
}
|
||||
if (!warnLoopStart.empty()) {
|
||||
ImGui::Text("%s",warnLoopStart.c_str());
|
||||
|
|
@ -719,7 +741,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
|
||||
pushWarningColor(!warnLoopPos.empty() || !warnLoopEnd.empty());
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("End");
|
||||
ImGui::Text(_("End"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputInt("##LoopEndPosition",&sample->loopEnd,1,16)) { MARK_MODIFIED
|
||||
|
|
@ -740,7 +762,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
if (ImGui::IsItemHovered() && (!warnLoopPos.empty() || !warnLoopEnd.empty() || sample->depth==DIV_SAMPLE_DEPTH_BRR)) {
|
||||
if (ImGui::BeginTooltip()) {
|
||||
if (sample->depth==DIV_SAMPLE_DEPTH_BRR) {
|
||||
ImGui::Text("changing the loop in a BRR sample may result in glitches!");
|
||||
ImGui::Text(_("changing the loop in a BRR sample may result in glitches!"));
|
||||
}
|
||||
if (!warnLoopEnd.empty()) {
|
||||
ImGui::Text("%s",warnLoopEnd.c_str());
|
||||
|
|
@ -829,13 +851,13 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
}
|
||||
String toolText;
|
||||
if (memName==NULL) {
|
||||
toolText=fmt::sprintf("%s\n%d bytes free",e->getSystemName(e->song.system[j]),totalFree);
|
||||
toolText=fmt::sprintf(_("%s\n%d bytes free"),e->getSystemName(e->song.system[j]),totalFree);
|
||||
} else {
|
||||
toolText=fmt::sprintf("%s (%s)\n%d bytes free",e->getSystemName(e->song.system[j]),memName,totalFree);
|
||||
toolText=fmt::sprintf(_("%s (%s)\n%d bytes free"),e->getSystemName(e->song.system[j]),memName,totalFree);
|
||||
}
|
||||
|
||||
if (isMemWarning[i][j] && sample->renderOn[i][j]) {
|
||||
toolText+="\n\nnot enough memory for this sample!";
|
||||
toolText+=_("\n\nnot enough memory for this sample!");
|
||||
}
|
||||
|
||||
ImGui::SetTooltip("%s",toolText.c_str());
|
||||
|
|
@ -859,7 +881,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
}
|
||||
popToggleColors();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Edit mode: Select");
|
||||
ImGui::SetTooltip(_("Edit mode: Select"));
|
||||
}
|
||||
sameLineMaybe();
|
||||
pushToggleColors(sampleDragMode);
|
||||
|
|
@ -868,7 +890,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
}
|
||||
popToggleColors();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Edit mode: Draw");
|
||||
ImGui::SetTooltip(_("Edit mode: Draw"));
|
||||
}
|
||||
ImGui::BeginDisabled(sample->depth!=DIV_SAMPLE_DEPTH_8BIT && sample->depth!=DIV_SAMPLE_DEPTH_16BIT);
|
||||
sameLineMaybe();
|
||||
|
|
@ -879,22 +901,22 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
resizeSize=sample->samples;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Resize");
|
||||
ImGui::SetTooltip(_("Resize"));
|
||||
}
|
||||
if (openSampleResizeOpt) {
|
||||
openSampleResizeOpt=false;
|
||||
ImGui::OpenPopup("SResizeOpt");
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("SResizeOpt",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
if (ImGui::InputInt("Samples",&resizeSize,1,64)) {
|
||||
if (ImGui::InputInt(_("Samples"),&resizeSize,1,64)) {
|
||||
if (resizeSize<0) resizeSize=0;
|
||||
if (resizeSize>16777215) resizeSize=16777215;
|
||||
}
|
||||
if (ImGui::Button("Resize")) {
|
||||
if (ImGui::Button(_("Resize"))) {
|
||||
sample->prepareUndo(true);
|
||||
e->lockEngine([this,sample]() {
|
||||
if (!sample->resize(resizeSize)) {
|
||||
showError("couldn't resize! make sure your sample is 8 or 16-bit.");
|
||||
showError(_("couldn't resize! make sure your sample is 8 or 16-bit."));
|
||||
}
|
||||
e->renderSamples(curSample);
|
||||
});
|
||||
|
|
@ -914,14 +936,14 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
resampleTarget=targetRate;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Resample");
|
||||
ImGui::SetTooltip(_("Resample"));
|
||||
}
|
||||
if (openSampleResampleOpt) {
|
||||
openSampleResampleOpt=false;
|
||||
ImGui::OpenPopup("SResampleOpt");
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("SResampleOpt",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
ImGui::Text("Rate");
|
||||
ImGui::Text(_("Rate"));
|
||||
if (ImGui::InputDouble("##SRRate",&resampleTarget,1.0,50.0,"%g")) {
|
||||
if (resampleTarget<0) resampleTarget=0;
|
||||
if (resampleTarget>96000) resampleTarget=96000;
|
||||
|
|
@ -939,17 +961,17 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
resampleTarget*=2.0;
|
||||
}
|
||||
double factor=resampleTarget/(double)targetRate;
|
||||
if (ImGui::InputDouble("Factor",&factor,0.125,0.5,"%g")) {
|
||||
if (ImGui::InputDouble(_("Factor"),&factor,0.125,0.5,"%g")) {
|
||||
resampleTarget=(double)targetRate*factor;
|
||||
if (resampleTarget<0) resampleTarget=0;
|
||||
if (resampleTarget>96000) resampleTarget=96000;
|
||||
}
|
||||
ImGui::Combo("Filter",&resampleStrat,resampleStrats,6);
|
||||
if (ImGui::Button("Resample")) {
|
||||
ImGui::Combo(_("Filter"),&resampleStrat,LocalizedComboGetter,resampleStrats,6);
|
||||
if (ImGui::Button(_("Resample"))) {
|
||||
sample->prepareUndo(true);
|
||||
e->lockEngine([this,sample,targetRate]() {
|
||||
if (!sample->resample(targetRate,resampleTarget,resampleStrat)) {
|
||||
showError("couldn't resample! make sure your sample is 8 or 16-bit.");
|
||||
showError(_("couldn't resample! make sure your sample is 8 or 16-bit."));
|
||||
}
|
||||
e->renderSamples(curSample);
|
||||
});
|
||||
|
|
@ -970,35 +992,35 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
doUndoSample();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Undo");
|
||||
ImGui::SetTooltip(_("Undo"));
|
||||
}
|
||||
sameLineMaybe();
|
||||
if (ImGui::Button(ICON_FA_REPEAT "##SRedo")) {
|
||||
doRedoSample();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Redo");
|
||||
ImGui::SetTooltip(_("Redo"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Dummy(ImVec2(4.0*dpiScale,dpiScale));
|
||||
sameLineMaybe();
|
||||
ImGui::Button(ICON_FA_VOLUME_UP "##SAmplify");
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Amplify");
|
||||
ImGui::SetTooltip(_("Amplify"));
|
||||
}
|
||||
if (openSampleAmplifyOpt) {
|
||||
openSampleAmplifyOpt=false;
|
||||
ImGui::OpenPopup("SAmplifyOpt");
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("SAmplifyOpt",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
ImGui::Text("Volume");
|
||||
ImGui::Text(_("Volume"));
|
||||
if (ImGui::InputFloat("##SRVolume",&lifyVol,10.0,50.0,"%g%%")) {
|
||||
if (amplifyVol<0) amplifyVol=0;
|
||||
if (amplifyVol>10000) amplifyVol=10000;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("(%.1fdB)",20.0*log10(amplifyVol/100.0f));
|
||||
if (ImGui::Button("Apply")) {
|
||||
if (ImGui::Button(_("Apply"))) {
|
||||
sample->prepareUndo(true);
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
|
@ -1034,42 +1056,42 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
doAction(GUI_ACTION_SAMPLE_NORMALIZE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Normalize");
|
||||
ImGui::SetTooltip(_("Normalize"));
|
||||
}
|
||||
sameLineMaybe();
|
||||
if (ImGui::Button(ICON_FUR_SAMPLE_FADEIN "##SFadeIn")) {
|
||||
doAction(GUI_ACTION_SAMPLE_FADE_IN);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Fade in");
|
||||
ImGui::SetTooltip(_("Fade in"));
|
||||
}
|
||||
sameLineMaybe();
|
||||
if (ImGui::Button(ICON_FUR_SAMPLE_FADEOUT "##SFadeOut")) {
|
||||
doAction(GUI_ACTION_SAMPLE_FADE_OUT);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Fade out");
|
||||
ImGui::SetTooltip(_("Fade out"));
|
||||
}
|
||||
sameLineMaybe();
|
||||
ImGui::Button(ICON_FUR_SAMPLE_INSERT_SILENCE "##SInsertSilence");
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Insert silence");
|
||||
ImGui::SetTooltip(_("Insert silence"));
|
||||
}
|
||||
if (openSampleSilenceOpt) {
|
||||
openSampleSilenceOpt=false;
|
||||
ImGui::OpenPopup("SSilenceOpt");
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("SSilenceOpt",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
if (ImGui::InputInt("Samples",&silenceSize,1,64)) {
|
||||
if (ImGui::InputInt(_("Samples"),&silenceSize,1,64)) {
|
||||
if (silenceSize<0) silenceSize=0;
|
||||
if (silenceSize>16777215) silenceSize=16777215;
|
||||
}
|
||||
if (ImGui::Button("Go")) {
|
||||
if (ImGui::Button(_("Go"))) {
|
||||
int pos=(sampleSelStart==-1 || sampleSelStart==sampleSelEnd)?sample->samples:sampleSelStart;
|
||||
sample->prepareUndo(true);
|
||||
e->lockEngine([this,sample,pos]() {
|
||||
if (!sample->insert(pos,silenceSize)) {
|
||||
showError("couldn't insert! make sure your sample is 8 or 16-bit.");
|
||||
showError(_("couldn't insert! make sure your sample is 8 or 16-bit."));
|
||||
}
|
||||
e->renderSamples(curSample);
|
||||
});
|
||||
|
|
@ -1086,21 +1108,21 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
doAction(GUI_ACTION_SAMPLE_SILENCE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Apply silence");
|
||||
ImGui::SetTooltip(_("Apply silence"));
|
||||
}
|
||||
sameLineMaybe();
|
||||
if (ImGui::Button(ICON_FA_TIMES "##SDelete")) {
|
||||
doAction(GUI_ACTION_SAMPLE_DELETE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Delete");
|
||||
ImGui::SetTooltip(_("Delete"));
|
||||
}
|
||||
sameLineMaybe();
|
||||
if (ImGui::Button(ICON_FA_CROP "##STrim")) {
|
||||
doAction(GUI_ACTION_SAMPLE_TRIM);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Trim");
|
||||
ImGui::SetTooltip(_("Trim"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Dummy(ImVec2(4.0*dpiScale,dpiScale));
|
||||
|
|
@ -1109,26 +1131,26 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
doAction(GUI_ACTION_SAMPLE_REVERSE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Reverse");
|
||||
ImGui::SetTooltip(_("Reverse"));
|
||||
}
|
||||
sameLineMaybe();
|
||||
if (ImGui::Button(ICON_FUR_SAMPLE_INVERT "##SInvert")) {
|
||||
doAction(GUI_ACTION_SAMPLE_INVERT);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Invert");
|
||||
ImGui::SetTooltip(_("Invert"));
|
||||
}
|
||||
sameLineMaybe();
|
||||
if (ImGui::Button(ICON_FUR_SAMPLE_SIGN "##SSign")) {
|
||||
doAction(GUI_ACTION_SAMPLE_SIGN);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Signed/unsigned exchange");
|
||||
ImGui::SetTooltip(_("Signed/unsigned exchange"));
|
||||
}
|
||||
sameLineMaybe();
|
||||
ImGui::Button(ICON_FUR_SAMPLE_FILTER "##SFilter");
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Apply filter");
|
||||
ImGui::SetTooltip(_("Apply filter"));
|
||||
}
|
||||
if (openSampleFilterOpt) {
|
||||
openSampleFilterOpt=false;
|
||||
|
|
@ -1139,23 +1161,23 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
float bandP=sampleFilterB*100.0f;
|
||||
float highP=sampleFilterH*100.0f;
|
||||
float resP=sampleFilterRes*100.0f;
|
||||
ImGui::Text("Cutoff:");
|
||||
if (ImGui::InputFloat("From",&sampleFilterCutStart,10.0f,1000.0f,"%.0f")) {
|
||||
ImGui::Text(_("Cutoff:"));
|
||||
if (ImGui::InputFloat(_("From"),&sampleFilterCutStart,10.0f,1000.0f,"%.0f")) {
|
||||
if (sampleFilterCutStart<0.0) sampleFilterCutStart=0.0;
|
||||
if (sampleFilterCutStart>sample->rate*0.5) sampleFilterCutStart=sample->rate*0.5;
|
||||
if (sampleFilterCutStart>sample->centerRate*0.5) sampleFilterCutStart=sample->centerRate*0.5;
|
||||
}
|
||||
if (ImGui::InputFloat("To",&sampleFilterCutEnd,10.0f,1000.0f,"%.0f")) {
|
||||
if (ImGui::InputFloat(_("To"),&sampleFilterCutEnd,10.0f,1000.0f,"%.0f")) {
|
||||
if (sampleFilterCutEnd<0.0) sampleFilterCutEnd=0.0;
|
||||
if (sampleFilterCutEnd>sample->rate*0.5) sampleFilterCutEnd=sample->rate*0.5;
|
||||
if (sampleFilterCutEnd>sample->centerRate*0.5) sampleFilterCutEnd=sample->centerRate*0.5;
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::SliderFloat("Resonance",&resP,0.0f,99.0f,"%.1f%%")) {
|
||||
if (ImGui::SliderFloat(_("Resonance"),&resP,0.0f,99.0f,"%.1f%%")) {
|
||||
sampleFilterRes=resP/100.0f;
|
||||
if (sampleFilterRes<0.0f) sampleFilterRes=0.0f;
|
||||
if (sampleFilterRes>0.99f) sampleFilterRes=0.99f;
|
||||
}
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Power");
|
||||
ImGui::Text(_("Power"));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("1x",sampleFilterPower==1)) {
|
||||
sampleFilterPower=1;
|
||||
|
|
@ -1169,23 +1191,23 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
sampleFilterPower=3;
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::SliderFloat("Low-pass",&lowP,0.0f,100.0f,"%.1f%%")) {
|
||||
if (ImGui::SliderFloat(_("Low-pass"),&lowP,0.0f,100.0f,"%.1f%%")) {
|
||||
sampleFilterL=lowP/100.0f;
|
||||
if (sampleFilterL<0.0f) sampleFilterL=0.0f;
|
||||
if (sampleFilterL>1.0f) sampleFilterL=1.0f;
|
||||
}
|
||||
if (ImGui::SliderFloat("Band-pass",&bandP,0.0f,100.0f,"%.1f%%")) {
|
||||
if (ImGui::SliderFloat(_("Band-pass"),&bandP,0.0f,100.0f,"%.1f%%")) {
|
||||
sampleFilterB=bandP/100.0f;
|
||||
if (sampleFilterB<0.0f) sampleFilterB=0.0f;
|
||||
if (sampleFilterB>1.0f) sampleFilterB=1.0f;
|
||||
}
|
||||
if (ImGui::SliderFloat("High-pass",&highP,0.0f,100.0f,"%.1f%%")) {
|
||||
if (ImGui::SliderFloat(_("High-pass"),&highP,0.0f,100.0f,"%.1f%%")) {
|
||||
sampleFilterH=highP/100.0f;
|
||||
if (sampleFilterH<0.0f) sampleFilterH=0.0f;
|
||||
if (sampleFilterH>1.0f) sampleFilterH=1.0f;
|
||||
}
|
||||
|
||||
if (ImGui::Button("Apply")) {
|
||||
if (ImGui::Button(_("Apply"))) {
|
||||
sample->prepareUndo(true);
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
|
@ -1194,12 +1216,17 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
float band=0;
|
||||
float high=0;
|
||||
|
||||
if (sampleFilterCutStart<0.0) sampleFilterCutStart=0.0;
|
||||
if (sampleFilterCutStart>sample->centerRate*0.5) sampleFilterCutStart=sample->centerRate*0.5;
|
||||
if (sampleFilterCutEnd<0.0) sampleFilterCutEnd=0.0;
|
||||
if (sampleFilterCutEnd>sample->centerRate*0.5) sampleFilterCutEnd=sample->centerRate*0.5;
|
||||
|
||||
double power=(sampleFilterCutStart>sampleFilterCutEnd)?0.5:2.0;
|
||||
|
||||
if (sample->depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
double freq=sampleFilterCutStart+(sampleFilterCutEnd-sampleFilterCutStart)*pow(double(i-start)/double(end-start),power);
|
||||
double cut=sin((freq/double(sample->rate))*M_PI);
|
||||
double cut=sin((freq/double(sample->centerRate))*M_PI);
|
||||
|
||||
for (int j=0; j<sampleFilterPower; j++) {
|
||||
low=low+cut*band;
|
||||
|
|
@ -1215,7 +1242,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
} else if (sample->depth==DIV_SAMPLE_DEPTH_8BIT) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
double freq=sampleFilterCutStart+(sampleFilterCutEnd-sampleFilterCutStart)*pow(double(i-start)/double(end-start),power);
|
||||
double cut=sin((freq/double(sample->rate))*M_PI);
|
||||
double cut=sin((freq/double(sample->centerRate))*M_PI);
|
||||
|
||||
for (int j=0; j<sampleFilterPower; j++) {
|
||||
low=low+cut*band;
|
||||
|
|
@ -1245,7 +1272,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
sameLineMaybe();
|
||||
ImGui::Button(ICON_FUR_CROSSFADE "##CrossFade");
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Crossfade loop points");
|
||||
ImGui::SetTooltip(_("Crossfade loop points"));
|
||||
}
|
||||
if (openSampleCrossFadeOpt) {
|
||||
openSampleCrossFadeOpt=false;
|
||||
|
|
@ -1254,22 +1281,22 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
if (ImGui::BeginPopupContextItem("SCrossFadeOpt",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
if (sampleCrossFadeLoopLength>sample->loopStart) sampleCrossFadeLoopLength=sample->loopStart;
|
||||
if (sampleCrossFadeLoopLength>(sample->loopEnd-sample->loopStart)) sampleCrossFadeLoopLength=sample->loopEnd-sample->loopStart;
|
||||
if (ImGui::SliderInt("Number of samples",&sampleCrossFadeLoopLength,0,100000)) {
|
||||
if (ImGui::SliderInt(_("Number of samples"),&sampleCrossFadeLoopLength,0,100000)) {
|
||||
if (sampleCrossFadeLoopLength<0) sampleCrossFadeLoopLength=0;
|
||||
if (sampleCrossFadeLoopLength>sample->loopStart) sampleCrossFadeLoopLength=sample->loopStart;
|
||||
if (sampleCrossFadeLoopLength>(sample->loopEnd-sample->loopStart)) sampleCrossFadeLoopLength=sample->loopEnd-sample->loopStart;
|
||||
if (sampleCrossFadeLoopLength>100000) sampleCrossFadeLoopLength=100000;
|
||||
}
|
||||
if (ImGui::SliderInt("Linear <-> Equal power",&sampleCrossFadeLoopLaw,0,100)) {
|
||||
if (ImGui::SliderInt(_("Linear <-> Equal power"),&sampleCrossFadeLoopLaw,0,100)) {
|
||||
if (sampleCrossFadeLoopLaw<0) sampleCrossFadeLoopLaw=0;
|
||||
if (sampleCrossFadeLoopLaw>100) sampleCrossFadeLoopLaw=100;
|
||||
}
|
||||
if (ImGui::Button("Apply")) {
|
||||
if (ImGui::Button(_("Apply"))) {
|
||||
if (sampleCrossFadeLoopLength>sample->loopStart) {
|
||||
showError("Crossfade: length would go out of bounds. Aborted...");
|
||||
showError(_("Crossfade: length would go out of bounds. Aborted..."));
|
||||
ImGui::CloseCurrentPopup();
|
||||
} else if (sampleCrossFadeLoopLength>(sample->loopEnd-sample->loopStart)) {
|
||||
showError("Crossfade: length would overflow loopStart. Try a smaller random value.");
|
||||
showError(_("Crossfade: length would overflow loopStart. Try a smaller random value."));
|
||||
ImGui::CloseCurrentPopup();
|
||||
} else {
|
||||
sample->prepareUndo(true);
|
||||
|
|
@ -1315,28 +1342,28 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
e->previewSample(curSample);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Preview sample");
|
||||
ImGui::SetTooltip(_("Preview sample"));
|
||||
}
|
||||
sameLineMaybe();
|
||||
if (ImGui::Button(ICON_FA_STOP "##StopSample")) {
|
||||
e->stopSamplePreview();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Stop sample preview");
|
||||
ImGui::SetTooltip(_("Stop sample preview"));
|
||||
}
|
||||
sameLineMaybe();
|
||||
if (ImGui::Button(ICON_FA_UPLOAD "##MakeIns")) {
|
||||
doAction(GUI_ACTION_SAMPLE_MAKE_INS);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Create instrument from sample");
|
||||
ImGui::SetTooltip(_("Create instrument from sample"));
|
||||
}
|
||||
|
||||
sameLineMaybe(ImGui::CalcTextSize("Zoom").x+150.0f*dpiScale+ImGui::CalcTextSize("100%").x);
|
||||
double zoomPercent=100.0/sampleZoom;
|
||||
bool checkZoomLimit=false;
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Zoom");
|
||||
ImGui::Text(_("Zoom"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(150.0f*dpiScale);
|
||||
if (ImGui::InputDouble("##SZoom",&zoomPercent,zoomPercent/8.0,20.0,"%g%%")) {
|
||||
|
|
@ -1464,14 +1491,14 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
}
|
||||
}
|
||||
|
||||
if (sampleTex==NULL || sampleTexW!=avail.x || sampleTexH!=avail.y) {
|
||||
if (sampleTex==NULL || sampleTexW!=avail.x || sampleTexH!=avail.y || !rend->isTextureValid(sampleTex)) {
|
||||
if (sampleTex!=NULL) {
|
||||
rend->destroyTexture(sampleTex);
|
||||
sampleTex=NULL;
|
||||
}
|
||||
if (avail.x>=1 && avail.y>=1) {
|
||||
logD("recreating sample texture.");
|
||||
sampleTex=rend->createTexture(true,avail.x,avail.y);
|
||||
sampleTex=rend->createTexture(true,avail.x,avail.y,true,bestTexFormat);
|
||||
sampleTexW=avail.x;
|
||||
sampleTexH=avail.y;
|
||||
if (sampleTex==NULL) {
|
||||
|
|
@ -1496,6 +1523,30 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
ImU32 bgColorLoop=ImGui::GetColorU32(uiColors[GUI_COLOR_SAMPLE_LOOP]);
|
||||
ImU32 lineColor=ImGui::GetColorU32(uiColors[GUI_COLOR_SAMPLE_FG]);
|
||||
ImU32 centerLineColor=ImGui::GetColorU32(uiColors[GUI_COLOR_SAMPLE_CENTER]);
|
||||
|
||||
switch (rend->getTextureFormat(sampleTex)) {
|
||||
case GUI_TEXFORMAT_ARGB32:
|
||||
SWAP_COLOR_ARGB(bgColor);
|
||||
SWAP_COLOR_ARGB(bgColorLoop);
|
||||
SWAP_COLOR_ARGB(lineColor);
|
||||
SWAP_COLOR_ARGB(centerLineColor);
|
||||
break;
|
||||
case GUI_TEXFORMAT_BGRA32:
|
||||
SWAP_COLOR_BGRA(bgColor);
|
||||
SWAP_COLOR_BGRA(bgColorLoop);
|
||||
SWAP_COLOR_BGRA(lineColor);
|
||||
SWAP_COLOR_BGRA(centerLineColor);
|
||||
break;
|
||||
case GUI_TEXFORMAT_RGBA32:
|
||||
SWAP_COLOR_RGBA(bgColor);
|
||||
SWAP_COLOR_RGBA(bgColorLoop);
|
||||
SWAP_COLOR_RGBA(lineColor);
|
||||
SWAP_COLOR_RGBA(centerLineColor);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int ij=0;
|
||||
for (int i=0; i<availY; i++) {
|
||||
for (int j=0; j<availX; j++) {
|
||||
|
|
@ -1589,7 +1640,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
updateSampleTex=false;
|
||||
}
|
||||
|
||||
ImGui::ImageButton(rend->getTextureID(sampleTex),avail,ImVec2(0,0),ImVec2(1,1),0);
|
||||
ImGui::ImageButton(rend->getTextureID(sampleTex),avail,ImVec2(0,0),ImVec2(rend->getTextureU(sampleTex),rend->getTextureV(sampleTex)),0);
|
||||
|
||||
ImVec2 rectMin=ImGui::GetItemRectMin();
|
||||
ImVec2 rectMax=ImGui::GetItemRectMax();
|
||||
|
|
@ -1695,40 +1746,40 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
|
||||
if (ImGui::BeginPopup("SRightClick",ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::BeginDisabled(sample->depth!=DIV_SAMPLE_DEPTH_8BIT && sample->depth!=DIV_SAMPLE_DEPTH_16BIT);
|
||||
if (ImGui::MenuItem("cut",BIND_FOR(GUI_ACTION_SAMPLE_CUT))) {
|
||||
if (ImGui::MenuItem(_("cut"),BIND_FOR(GUI_ACTION_SAMPLE_CUT))) {
|
||||
doAction(GUI_ACTION_SAMPLE_CUT);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
if (ImGui::MenuItem("copy",BIND_FOR(GUI_ACTION_SAMPLE_COPY))) {
|
||||
if (ImGui::MenuItem(_("copy"),BIND_FOR(GUI_ACTION_SAMPLE_COPY))) {
|
||||
doAction(GUI_ACTION_SAMPLE_COPY);
|
||||
}
|
||||
ImGui::BeginDisabled(sample->depth!=DIV_SAMPLE_DEPTH_8BIT && sample->depth!=DIV_SAMPLE_DEPTH_16BIT);
|
||||
if (ImGui::MenuItem("paste",BIND_FOR(GUI_ACTION_SAMPLE_PASTE))) {
|
||||
if (ImGui::MenuItem(_("paste"),BIND_FOR(GUI_ACTION_SAMPLE_PASTE))) {
|
||||
doAction(GUI_ACTION_SAMPLE_PASTE);
|
||||
}
|
||||
if (ImGui::MenuItem("paste (replace)",BIND_FOR(GUI_ACTION_SAMPLE_PASTE_REPLACE))) {
|
||||
if (ImGui::MenuItem(_("paste (replace)"),BIND_FOR(GUI_ACTION_SAMPLE_PASTE_REPLACE))) {
|
||||
doAction(GUI_ACTION_SAMPLE_PASTE_REPLACE);
|
||||
}
|
||||
if (ImGui::MenuItem("paste (mix)",BIND_FOR(GUI_ACTION_SAMPLE_PASTE_MIX))) {
|
||||
if (ImGui::MenuItem(_("paste (mix)"),BIND_FOR(GUI_ACTION_SAMPLE_PASTE_MIX))) {
|
||||
doAction(GUI_ACTION_SAMPLE_PASTE_MIX);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
if (ImGui::MenuItem("select all",BIND_FOR(GUI_ACTION_SAMPLE_SELECT_ALL))) {
|
||||
if (ImGui::MenuItem(_("select all"),BIND_FOR(GUI_ACTION_SAMPLE_SELECT_ALL))) {
|
||||
doAction(GUI_ACTION_SAMPLE_SELECT_ALL);
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("set loop to selection",BIND_FOR(GUI_ACTION_SAMPLE_SET_LOOP))) {
|
||||
if (ImGui::MenuItem(_("set loop to selection"),BIND_FOR(GUI_ACTION_SAMPLE_SET_LOOP))) {
|
||||
doAction(GUI_ACTION_SAMPLE_SET_LOOP);
|
||||
}
|
||||
if (ImGui::MenuItem("create wavetable from selection",BIND_FOR(GUI_ACTION_SAMPLE_CREATE_WAVE))) {
|
||||
if (ImGui::MenuItem(_("create wavetable from selection"),BIND_FOR(GUI_ACTION_SAMPLE_CREATE_WAVE))) {
|
||||
doAction(GUI_ACTION_SAMPLE_CREATE_WAVE);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
String statusBar=sampleDragMode?"Draw":"Select";
|
||||
String statusBar=sampleDragMode?_("Draw"):_("Select");
|
||||
String statusBar2="";
|
||||
String statusBar3=fmt::sprintf("%d samples, %d bytes",sample->samples,sample->getCurBufLen());
|
||||
String statusBar3=fmt::sprintf(_("%d samples, %d bytes"),sample->samples,sample->getCurBufLen());
|
||||
bool drawSelection=false;
|
||||
|
||||
if (!sampleDragMode) {
|
||||
|
|
@ -1743,7 +1794,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
if (start==end) {
|
||||
statusBar+=fmt::sprintf(" (%d)",start);
|
||||
} else {
|
||||
statusBar+=fmt::sprintf(" (%d-%d: %d samples)",start,end,end-start);
|
||||
statusBar+=fmt::sprintf(_(" (%d-%d: %d samples)"),start,end,end-start);
|
||||
}
|
||||
drawSelection=true;
|
||||
}
|
||||
|
|
@ -1935,7 +1986,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
}
|
||||
|
||||
if (sample->depth!=DIV_SAMPLE_DEPTH_8BIT && sample->depth!=DIV_SAMPLE_DEPTH_16BIT && sampleDragMode) {
|
||||
statusBar="Non-8/16-bit samples cannot be edited without prior conversion.";
|
||||
statusBar=_("Non-8/16-bit samples cannot be edited without prior conversion.");
|
||||
}
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY()+ImGui::GetStyle().ScrollbarSize);
|
||||
|
|
|
|||
3585
src/gui/settings.cpp
3585
src/gui/settings.cpp
File diff suppressed because it is too large
Load diff
|
|
@ -29,7 +29,7 @@ void FurnaceGUI::drawSongInfo(bool asChild) {
|
|||
nextWindow=GUI_WINDOW_NOTHING;
|
||||
}
|
||||
if (!songInfoOpen && !asChild) return;
|
||||
bool began=asChild?ImGui::BeginChild("Song Info##Song Information"):ImGui::Begin("Song Info##Song Information",&songInfoOpen,globalWinFlags);
|
||||
bool began=asChild?ImGui::BeginChild("Song Info##Song Information"):ImGui::Begin("Song Info##Song Information",&songInfoOpen,globalWinFlags,_("Song Info##Song Information"));
|
||||
if (began) {
|
||||
if (ImGui::BeginTable("NameAuthor",2,ImGuiTableFlags_SizingStretchProp)) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,0.0);
|
||||
|
|
@ -37,7 +37,7 @@ void FurnaceGUI::drawSongInfo(bool asChild) {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Name");
|
||||
ImGui::Text(_("Name"));
|
||||
ImGui::TableNextColumn();
|
||||
float avail=ImGui::GetContentRegionAvail().x;
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
|
|
@ -47,7 +47,7 @@ void FurnaceGUI::drawSongInfo(bool asChild) {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Author");
|
||||
ImGui::Text(_("Author"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
if (ImGui::InputText("##Author",&e->song.author,ImGuiInputTextFlags_UndoRedo)) {
|
||||
|
|
@ -57,7 +57,7 @@ void FurnaceGUI::drawSongInfo(bool asChild) {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Album");
|
||||
ImGui::Text(_("Album"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
if (ImGui::InputText("##Category",&e->song.category,ImGuiInputTextFlags_UndoRedo)) {
|
||||
|
|
@ -66,7 +66,7 @@ void FurnaceGUI::drawSongInfo(bool asChild) {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("System");
|
||||
ImGui::Text(_("System"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(MAX(16.0f*dpiScale,avail-autoButtonSize-ImGui::GetStyle().ItemSpacing.x));
|
||||
if (ImGui::InputText("##SystemName",&e->song.systemName,ImGuiInputTextFlags_UndoRedo)) {
|
||||
|
|
@ -76,7 +76,7 @@ void FurnaceGUI::drawSongInfo(bool asChild) {
|
|||
}
|
||||
ImGui::SameLine();
|
||||
pushToggleColors(e->song.autoSystem);
|
||||
if (ImGui::Button("Auto")) {
|
||||
if (ImGui::Button(_("Auto"))) {
|
||||
e->song.autoSystem=!e->song.autoSystem;
|
||||
if (e->song.autoSystem) {
|
||||
autoDetectSystem();
|
||||
|
|
@ -97,7 +97,7 @@ void FurnaceGUI::drawSongInfo(bool asChild) {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Tuning (A-4)");
|
||||
ImGui::Text(_("Tuning (A-4)"));
|
||||
ImGui::TableNextColumn();
|
||||
float tune=e->song.tuning;
|
||||
float avail=ImGui::GetContentRegionAvail().x;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ void FurnaceGUI::drawNotes() {
|
|||
nextWindow=GUI_WINDOW_NOTHING;
|
||||
}
|
||||
if (!notesOpen) return;
|
||||
if (ImGui::Begin("Song Comments",¬esOpen,globalWinFlags)) {
|
||||
if (ImGui::Begin("Song Comments",¬esOpen,globalWinFlags,_("Song Comments"))) {
|
||||
if (ImGui::InputTextMultiline("##SongNotes",&e->song.notes,ImGui::GetContentRegionAvail(),ImGuiInputTextFlags_UndoRedo)) {
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ void FurnaceGUI::drawSpeed(bool asChild) {
|
|||
nextWindow=GUI_WINDOW_NOTHING;
|
||||
}
|
||||
if (!speedOpen && !asChild) return;
|
||||
bool began=asChild?ImGui::BeginChild("Speed"):ImGui::Begin("Speed",&speedOpen,globalWinFlags);
|
||||
bool began=asChild?ImGui::BeginChild("Speed"):ImGui::Begin("Speed",&speedOpen,globalWinFlags,_("Speed"));
|
||||
if (began) {
|
||||
if (ImGui::BeginTable("Props",2,ImGuiTableFlags_SizingStretchProp)) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,0.0);
|
||||
|
|
@ -38,14 +38,14 @@ void FurnaceGUI::drawSpeed(bool asChild) {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
if (ImGui::SmallButton(tempoView?"Base Tempo##TempoOrHz":"Tick Rate##TempoOrHz")) {
|
||||
if (ImGui::SmallButton(tempoView?_("Base Tempo##TempoOrHz"):_("Tick Rate##TempoOrHz"))) {
|
||||
tempoView=!tempoView;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
if (tempoView) {
|
||||
ImGui::SetTooltip("click to display tick rate");
|
||||
ImGui::SetTooltip(_("click to display tick rate"));
|
||||
} else {
|
||||
ImGui::SetTooltip("click to display base tempo");
|
||||
ImGui::SetTooltip(_("click to display base tempo"));
|
||||
}
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
|
|
@ -77,17 +77,17 @@ void FurnaceGUI::drawSpeed(bool asChild) {
|
|||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
if (keepGrooveAlive || e->curSubSong->speeds.len>2) {
|
||||
if (ImGui::SmallButton("Groove")) {
|
||||
if (ImGui::SmallButton(_("Groove"))) {
|
||||
e->lockEngine([this]() {
|
||||
e->curSubSong->speeds.len=1;
|
||||
});
|
||||
if (e->isPlaying()) play();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("click for one speed");
|
||||
ImGui::SetTooltip(_("click for one speed"));
|
||||
}
|
||||
} else if (e->curSubSong->speeds.len>1) {
|
||||
if (ImGui::SmallButton("Speeds")) {
|
||||
if (ImGui::SmallButton(_("Speeds"))) {
|
||||
e->lockEngine([this]() {
|
||||
e->curSubSong->speeds.len=4;
|
||||
e->curSubSong->speeds.val[2]=e->curSubSong->speeds.val[0];
|
||||
|
|
@ -96,10 +96,10 @@ void FurnaceGUI::drawSpeed(bool asChild) {
|
|||
if (e->isPlaying()) play();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("click for groove pattern");
|
||||
ImGui::SetTooltip(_("click for groove pattern"));
|
||||
}
|
||||
} else {
|
||||
if (ImGui::SmallButton("Speed")) {
|
||||
if (ImGui::SmallButton(_("Speed"))) {
|
||||
e->lockEngine([this]() {
|
||||
e->curSubSong->speeds.len=2;
|
||||
e->curSubSong->speeds.val[1]=e->curSubSong->speeds.val[0];
|
||||
|
|
@ -107,7 +107,7 @@ void FurnaceGUI::drawSpeed(bool asChild) {
|
|||
if (e->isPlaying()) play();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("click for two (alternating) speeds");
|
||||
ImGui::SetTooltip(_("click for two (alternating) speeds"));
|
||||
}
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
|
|
@ -165,7 +165,7 @@ void FurnaceGUI::drawSpeed(bool asChild) {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Virtual Tempo");
|
||||
ImGui::Text(_("Virtual Tempo"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(halfAvail);
|
||||
if (ImGui::InputScalar("##VTempoN",ImGuiDataType_S16,&e->curSubSong->virtualTempoN,&_ONE,&_TEN)) { MARK_MODIFIED
|
||||
|
|
@ -174,7 +174,7 @@ void FurnaceGUI::drawSpeed(bool asChild) {
|
|||
e->virtualTempoChanged();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Numerator");
|
||||
ImGui::SetTooltip(_("Numerator"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(halfAvail);
|
||||
|
|
@ -184,13 +184,13 @@ void FurnaceGUI::drawSpeed(bool asChild) {
|
|||
e->virtualTempoChanged();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Denominator (set to base tempo)");
|
||||
ImGui::SetTooltip(_("Denominator (set to base tempo)"));
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Divider");
|
||||
ImGui::Text(_("Divider"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(halfAvail);
|
||||
unsigned char realTB=e->curSubSong->timeBase+1;
|
||||
|
|
@ -205,7 +205,7 @@ void FurnaceGUI::drawSpeed(bool asChild) {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Highlight");
|
||||
ImGui::Text(_("Highlight"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(halfAvail);
|
||||
if (ImGui::InputScalar("##Highlight1",ImGuiDataType_U8,&e->curSubSong->hilightA,&_ONE,&_FOUR)) {
|
||||
|
|
@ -228,7 +228,7 @@ void FurnaceGUI::drawSpeed(bool asChild) {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Pattern Length");
|
||||
ImGui::Text(_("Pattern Length"));
|
||||
ImGui::TableNextColumn();
|
||||
float avail=ImGui::GetContentRegionAvail().x;
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
|
|
@ -242,7 +242,7 @@ void FurnaceGUI::drawSpeed(bool asChild) {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Song Length");
|
||||
ImGui::Text(_("Song Length"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(avail);
|
||||
int ordLen=e->curSubSong->ordersLen;
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ void FurnaceGUI::drawSpoiler() {
|
|||
nextWindow=GUI_WINDOW_NOTHING;
|
||||
}
|
||||
if (!spoilerOpen) return;
|
||||
if (ImGui::Begin("Spoiler",&spoilerOpen,globalWinFlags|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
if (ImGui::Begin("Spoiler",&spoilerOpen,globalWinFlags|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_AlwaysAutoResize,_("Spoiler"))) {
|
||||
ImGui::PushFont(bigFont);
|
||||
ImGui::Text("SPOILER");
|
||||
ImGui::Text(_("SPOILER"));
|
||||
ImGui::PopFont();
|
||||
}
|
||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_SPOILER;
|
||||
|
|
|
|||
|
|
@ -28,12 +28,12 @@ void FurnaceGUI::drawStats() {
|
|||
nextWindow=GUI_WINDOW_NOTHING;
|
||||
}
|
||||
if (!statsOpen) return;
|
||||
if (ImGui::Begin("Statistics",&statsOpen,globalWinFlags)) {
|
||||
if (ImGui::Begin("Statistics",&statsOpen,globalWinFlags,_("Statistics"))) {
|
||||
size_t lastProcTime=e->processTime;
|
||||
double maxGot=1000000000.0*(double)e->getAudioDescGot().bufsize/(double)e->getAudioDescGot().rate;
|
||||
String procStr=fmt::sprintf("%.1f%%",100.0*((double)lastProcTime/(double)maxGot));
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Audio load");
|
||||
ImGui::Text(_("Audio load"));
|
||||
ImGui::SameLine();
|
||||
ImGui::ProgressBar((double)lastProcTime/maxGot,ImVec2(-FLT_MIN,0),procStr.c_str());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ void FurnaceGUI::drawSubSongs(bool asChild) {
|
|||
if (!asChild) {
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(64.0f*dpiScale,32.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||
}
|
||||
bool began=asChild?ImGui::BeginChild("Subsongs"):ImGui::Begin("Subsongs",&subSongsOpen,globalWinFlags);
|
||||
bool began=asChild?ImGui::BeginChild("Subsongs"):ImGui::Begin("Subsongs",&subSongsOpen,globalWinFlags,_("Subsongs"));
|
||||
if (began) {
|
||||
char id[1024];
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-ImGui::GetFrameHeightWithSpacing()*3.0f-ImGui::GetStyle().ItemSpacing.x*2.0f);
|
||||
if (e->curSubSong->name.empty()) {
|
||||
snprintf(id,1023,"%d. <no name>",(int)e->getCurrentSubSong()+1);
|
||||
snprintf(id,1023,_("%d. <no name>"),(int)e->getCurrentSubSong()+1);
|
||||
} else {
|
||||
snprintf(id,1023,"%d. %s",(int)e->getCurrentSubSong()+1,e->curSubSong->name.c_str());
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ void FurnaceGUI::drawSubSongs(bool asChild) {
|
|||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed);
|
||||
for (size_t i=0; i<e->song.subsong.size(); i++) {
|
||||
if (e->song.subsong[i]->name.empty()) {
|
||||
snprintf(id,1023,"%d. <no name>",(int)i+1);
|
||||
snprintf(id,1023,_("%d. <no name>"),(int)i+1);
|
||||
} else {
|
||||
snprintf(id,1023,"%d. %s",(int)i+1,e->song.subsong[i]->name.c_str());
|
||||
}
|
||||
|
|
@ -52,14 +52,14 @@ void FurnaceGUI::drawSubSongs(bool asChild) {
|
|||
e->moveSubSongUp(i);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Move up");
|
||||
ImGui::SetTooltip(_("Move up"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton(ICON_FA_ARROW_DOWN "##SubDown")) {
|
||||
e->moveSubSongDown(i);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Move down");
|
||||
ImGui::SetTooltip(_("Move down"));
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
|
@ -70,7 +70,7 @@ void FurnaceGUI::drawSubSongs(bool asChild) {
|
|||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_PLUS "##SubSongAdd")) {
|
||||
if (!e->addSubSong()) {
|
||||
showError("too many subsongs!");
|
||||
showError(_("too many subsongs!"));
|
||||
} else {
|
||||
e->changeSongP(e->song.subsong.size()-1);
|
||||
updateScroll(0);
|
||||
|
|
@ -85,12 +85,12 @@ void FurnaceGUI::drawSubSongs(bool asChild) {
|
|||
}
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Add");
|
||||
ImGui::SetTooltip(_("Add"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_FILES_O "##SubSongDuplicate")) {
|
||||
if (!e->duplicateSubSong(e->getCurrentSubSong())) {
|
||||
showError("too many subsongs!");
|
||||
showError(_("too many subsongs!"));
|
||||
} else {
|
||||
e->changeSongP(e->song.subsong.size()-1);
|
||||
updateScroll(0);
|
||||
|
|
@ -105,24 +105,24 @@ void FurnaceGUI::drawSubSongs(bool asChild) {
|
|||
}
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Duplicate");
|
||||
ImGui::SetTooltip(_("Duplicate"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
pushDestColor();
|
||||
if (ImGui::Button(ICON_FA_MINUS "##SubSongDel")) {
|
||||
if (e->song.subsong.size()<=1) {
|
||||
showError("this is the only subsong!");
|
||||
showError(_("this is the only subsong!"));
|
||||
} else {
|
||||
showWarning("are you sure you want to remove this subsong?",GUI_WARN_SUBSONG_DEL);
|
||||
showWarning(_("are you sure you want to remove this subsong?"),GUI_WARN_SUBSONG_DEL);
|
||||
}
|
||||
}
|
||||
popDestColor();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Remove");
|
||||
ImGui::SetTooltip(_("Remove"));
|
||||
}
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Name");
|
||||
ImGui::Text(_("Name"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputText("##SubSongName",&e->curSubSong->name,ImGuiInputTextFlags_UndoRedo)) {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -38,12 +38,12 @@ void FurnaceGUI::drawSysManager() {
|
|||
} else {
|
||||
//ImGui::SetNextWindowSizeConstraints(ImVec2(440.0f*dpiScale,400.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||
}
|
||||
if (ImGui::Begin("Chip Manager",&sysManagerOpen,globalWinFlags)) {
|
||||
ImGui::Checkbox("Preserve channel order",&preserveChanPos);
|
||||
if (ImGui::Begin("Chip Manager",&sysManagerOpen,globalWinFlags,_("Chip Manager"))) {
|
||||
ImGui::Checkbox(_("Preserve channel order"),&preserveChanPos);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Clone channel data",&sysDupCloneChannels);
|
||||
ImGui::Checkbox(_("Clone channel data"),&sysDupCloneChannels);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Clone at end",&sysDupEnd);
|
||||
ImGui::Checkbox(_("Clone at end"),&sysDupEnd);
|
||||
if (ImGui::BeginTable("SystemList",3)) {
|
||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch);
|
||||
|
|
@ -51,9 +51,9 @@ void FurnaceGUI::drawSysManager() {
|
|||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Name");
|
||||
ImGui::Text(_("Name"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Actions");
|
||||
ImGui::Text(_("Actions"));
|
||||
for (unsigned char i=0; i<e->song.systemLen; i++) {
|
||||
ImGui::PushID(i);
|
||||
ImGui::TableNextRow();
|
||||
|
|
@ -66,7 +66,7 @@ void FurnaceGUI::drawSysManager() {
|
|||
ImGui::Button(ICON_FA_ARROWS "##SysDrag");
|
||||
ImGui::EndDragDropSource();
|
||||
} else if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("(drag to swap chips)");
|
||||
ImGui::SetTooltip(_("(drag to swap chips)"));
|
||||
}
|
||||
if (ImGui::BeginDragDropTarget()) {
|
||||
const ImGuiPayload* dragItem=ImGui::AcceptDragDropPayload("FUR_SYS");
|
||||
|
|
@ -102,15 +102,20 @@ void FurnaceGUI::drawSysManager() {
|
|||
}
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Clone##SysDup")) {
|
||||
if (ImGui::Button(_("Clone##SysDup"))) {
|
||||
if (!e->duplicateSystem(i,sysDupCloneChannels,sysDupEnd)) {
|
||||
showError("cannot clone chip! ("+e->getLastError()+")");
|
||||
showError(fmt::sprintf(_("cannot clone chip! (%s)"),e->getLastError()));
|
||||
} else {
|
||||
if (e->song.autoSystem) {
|
||||
autoDetectSystem();
|
||||
updateWindowTitle();
|
||||
}
|
||||
updateROMExportAvail();
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Button("Change##SysChange");
|
||||
ImGui::Button(_("Change##SysChange"));
|
||||
if (ImGui::BeginPopupContextItem("SysPickerC",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
DivSystem picked=systemPicker();
|
||||
if (picked!=DIV_SYSTEM_NULL) {
|
||||
|
|
@ -120,8 +125,9 @@ void FurnaceGUI::drawSysManager() {
|
|||
autoDetectSystem();
|
||||
}
|
||||
updateWindowTitle();
|
||||
updateROMExportAvail();
|
||||
} else {
|
||||
showError("cannot change chip! ("+e->getLastError()+")");
|
||||
showError(fmt::sprintf(_("cannot change chip! (%s)"),e->getLastError()));
|
||||
}
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
|
@ -132,11 +138,11 @@ void FurnaceGUI::drawSysManager() {
|
|||
pushDestColor();
|
||||
if (ImGui::Button(ICON_FA_TIMES "##SysRemove")) {
|
||||
sysToDelete=i;
|
||||
showWarning("Are you sure you want to remove this chip?",GUI_WARN_SYSTEM_DEL);
|
||||
showWarning(_("Are you sure you want to remove this chip?"),GUI_WARN_SYSTEM_DEL);
|
||||
}
|
||||
popDestColor();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Remove");
|
||||
ImGui::SetTooltip(_("Remove"));
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::PopID();
|
||||
|
|
@ -150,7 +156,7 @@ void FurnaceGUI::drawSysManager() {
|
|||
DivSystem picked=systemPicker();
|
||||
if (picked!=DIV_SYSTEM_NULL) {
|
||||
if (!e->addSystem(picked)) {
|
||||
showError("cannot add chip! ("+e->getLastError()+")");
|
||||
showError(fmt::sprintf(_("cannot add chip! (%s)"),e->getLastError()));
|
||||
} else {
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
|
|
@ -158,6 +164,7 @@ void FurnaceGUI::drawSysManager() {
|
|||
autoDetectSystem();
|
||||
}
|
||||
updateWindowTitle();
|
||||
updateROMExportAvail();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
|
|
|
|||
|
|
@ -32,10 +32,10 @@ DivSystem FurnaceGUI::systemPicker() {
|
|||
}
|
||||
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputTextWithHint("##SysSearch","Search...",&sysSearchQuery)) reissueSearch=true;
|
||||
if (ImGui::InputTextWithHint("##SysSearch",_("Search..."),&sysSearchQuery)) reissueSearch=true;
|
||||
if (ImGui::BeginTabBar("SysCats")) {
|
||||
for (int i=0; chipCategories[i]; i++) {
|
||||
if (ImGui::BeginTabItem(chipCategoryNames[i])) {
|
||||
if (ImGui::BeginTabItem(_(chipCategoryNames[i]))) {
|
||||
if (ImGui::IsItemActive()) {
|
||||
reissueSearch=true;
|
||||
}
|
||||
|
|
@ -96,4 +96,4 @@ DivSystem FurnaceGUI::systemPicker() {
|
|||
}
|
||||
ImGui::EndChild();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1758
src/gui/tileData.h
Normal file
1758
src/gui/tileData.h
Normal file
File diff suppressed because it is too large
Load diff
3057
src/gui/tutorial.cpp
3057
src/gui/tutorial.cpp
File diff suppressed because it is too large
Load diff
532
src/gui/userPresets.cpp
Normal file
532
src/gui/userPresets.cpp
Normal file
|
|
@ -0,0 +1,532 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2024 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 "../baseutils.h"
|
||||
#include "../fileutils.h"
|
||||
#include <fmt/printf.h>
|
||||
#include "IconsFontAwesome4.h"
|
||||
#include <imgui.h>
|
||||
#include "misc/cpp/imgui_stdlib.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PRESETS_FILE "\\presets.cfg"
|
||||
#else
|
||||
#define PRESETS_FILE "/presets.cfg"
|
||||
#endif
|
||||
|
||||
#define REDUNDANCY_NUM_ATTEMPTS 5
|
||||
#define CHECK_BUF_SIZE 8192
|
||||
|
||||
std::vector<FurnaceGUISysDef>* digDeep(std::vector<FurnaceGUISysDef>& entries, int depth) {
|
||||
if (depth==0) return &entries;
|
||||
std::vector<FurnaceGUISysDef>& result=entries;
|
||||
|
||||
for (int i=0; i<depth; i++) {
|
||||
if (result.empty()) {
|
||||
logW("digDeep: %d is as far as it goes!",depth);
|
||||
break;
|
||||
}
|
||||
result=result.at(result.size()).subDefs;
|
||||
}
|
||||
return &result;
|
||||
}
|
||||
|
||||
bool FurnaceGUI::loadUserPresets(bool redundancy, String path, bool append) {
|
||||
if (path.empty()) path=e->getConfigPath()+PRESETS_FILE;
|
||||
String line;
|
||||
logD("opening user presets: %s",path);
|
||||
|
||||
FILE* f=NULL;
|
||||
|
||||
if (redundancy) {
|
||||
unsigned char* readBuf=new unsigned char[CHECK_BUF_SIZE];
|
||||
size_t readBufLen=0;
|
||||
for (int i=0; i<REDUNDANCY_NUM_ATTEMPTS; i++) {
|
||||
bool viable=false;
|
||||
if (i>0) {
|
||||
line=fmt::sprintf("%s.%d",path,i);
|
||||
} else {
|
||||
line=path;
|
||||
}
|
||||
logV("trying: %s",line);
|
||||
|
||||
// try to open config
|
||||
f=ps_fopen(line.c_str(),"rb");
|
||||
// check whether we could open it
|
||||
if (f==NULL) {
|
||||
logV("fopen(): %s",strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
// check whether there's something
|
||||
while (!feof(f)) {
|
||||
readBufLen=fread(readBuf,1,CHECK_BUF_SIZE,f);
|
||||
if (ferror(f)) {
|
||||
logV("fread(): %s",strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
for (size_t j=0; j<readBufLen; j++) {
|
||||
if (readBuf[j]==0) {
|
||||
viable=false;
|
||||
logW("a zero?");
|
||||
break;
|
||||
}
|
||||
if (readBuf[j]!='\r' && readBuf[j]!='\n' && readBuf[j]!=' ') {
|
||||
viable=true;
|
||||
}
|
||||
}
|
||||
|
||||
if (viable) break;
|
||||
}
|
||||
|
||||
// there's something
|
||||
if (viable) {
|
||||
if (fseek(f,0,SEEK_SET)==-1) {
|
||||
logV("fseek(): %s",strerror(errno));
|
||||
viable=false;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// close it (because there's nothing)
|
||||
fclose(f);
|
||||
f=NULL;
|
||||
}
|
||||
delete[] readBuf;
|
||||
|
||||
// we couldn't read at all
|
||||
if (f==NULL) {
|
||||
logD("presets file does not exist");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
f=ps_fopen(path.c_str(),"rb");
|
||||
if (f==NULL) {
|
||||
logD("presets file does not exist");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// now read stuff
|
||||
FurnaceGUISysCategory* userCategory=NULL;
|
||||
|
||||
for (FurnaceGUISysCategory& i: sysCategories) {
|
||||
if (strcmp(i.name,"User")==0) {
|
||||
userCategory=&i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (userCategory==NULL) {
|
||||
logE("could not find user category!");
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!append) userCategory->systems.clear();
|
||||
|
||||
char nextLine[4096];
|
||||
while (!feof(f)) {
|
||||
if (fgets(nextLine,4095,f)==NULL) {
|
||||
break;
|
||||
}
|
||||
int indent=0;
|
||||
bool readIndent=true;
|
||||
bool keyOrValue=false;
|
||||
String key="";
|
||||
String value="";
|
||||
for (char* i=nextLine; *i; i++) {
|
||||
if ((*i)=='\n') break;
|
||||
if (readIndent) {
|
||||
if ((*i)==' ') {
|
||||
indent++;
|
||||
} else {
|
||||
readIndent=false;
|
||||
}
|
||||
}
|
||||
if (!readIndent) {
|
||||
if (keyOrValue) {
|
||||
value+=*i;
|
||||
} else {
|
||||
if ((*i)=='=') {
|
||||
keyOrValue=true;
|
||||
} else {
|
||||
key+=*i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
indent>>=1;
|
||||
|
||||
if (!key.empty()) {
|
||||
std::vector<FurnaceGUISysDef>* where=digDeep(userCategory->systems,indent);
|
||||
where->push_back(FurnaceGUISysDef(key.c_str(),value.c_str(),e));
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
void writeSubEntries(FILE* f, std::vector<FurnaceGUISysDef>& entries, int depth) {
|
||||
for (FurnaceGUISysDef& i: entries) {
|
||||
String safeName;
|
||||
safeName.reserve(i.name.size());
|
||||
bool beginning=false;
|
||||
for (unsigned char j: i.name) {
|
||||
if (beginning && j==' ') continue;
|
||||
if (j=='=') continue;
|
||||
if (j<0x20) continue;
|
||||
safeName+=j;
|
||||
}
|
||||
|
||||
String data;
|
||||
for (int i=0; i<depth; i++) {
|
||||
data+=" ";
|
||||
}
|
||||
data+=fmt::sprintf("%s=%s\n",safeName,taEncodeBase64(i.definition));
|
||||
fputs(data.c_str(),f);
|
||||
|
||||
writeSubEntries(f,i.subDefs,depth+1);
|
||||
}
|
||||
}
|
||||
|
||||
bool FurnaceGUI::saveUserPresets(bool redundancy, String path) {
|
||||
if (path.empty()) path=e->getConfigPath()+PRESETS_FILE;
|
||||
FurnaceGUISysCategory* userCategory=NULL;
|
||||
|
||||
for (FurnaceGUISysCategory& i: sysCategories) {
|
||||
if (strcmp(i.name,"User")==0) {
|
||||
userCategory=&i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (userCategory==NULL) {
|
||||
logE("could not find user category!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (redundancy) {
|
||||
char oldPath[4096];
|
||||
char newPath[4096];
|
||||
|
||||
if (fileExists(path.c_str())==1) {
|
||||
logD("rotating preset files...");
|
||||
for (int i=4; i>=0; i--) {
|
||||
if (i>0) {
|
||||
snprintf(oldPath,4095,"%s.%d",path.c_str(),i);
|
||||
} else {
|
||||
strncpy(oldPath,path.c_str(),4095);
|
||||
}
|
||||
snprintf(newPath,4095,"%s.%d",path.c_str(),i+1);
|
||||
|
||||
if (i>=4) {
|
||||
logV("remove %s",oldPath);
|
||||
deleteFile(oldPath);
|
||||
} else {
|
||||
logV("move %s to %s",oldPath,newPath);
|
||||
moveFiles(oldPath,newPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
logD("saving user presets: %s",path);
|
||||
FILE* f=ps_fopen(path.c_str(),"wb");
|
||||
if (f==NULL) {
|
||||
logW("could not write presets! %s",strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
writeSubEntries(f,userCategory->systems,0);
|
||||
|
||||
fclose(f);
|
||||
logD("presets written successfully.");
|
||||
return true;
|
||||
}
|
||||
|
||||
// user presets management
|
||||
void FurnaceGUI::printPresets(std::vector<FurnaceGUISysDef>& items, size_t depth, std::vector<int>& depthStack) {
|
||||
if (depth>0) ImGui::Indent();
|
||||
int index=0;
|
||||
for (FurnaceGUISysDef& i: items) {
|
||||
bool isSelected=(selectedUserPreset.size()==(depth+1));
|
||||
if (isSelected) {
|
||||
for (size_t j=0; j<=depth; j++) {
|
||||
int item=-1;
|
||||
if (j>=depthStack.size()) {
|
||||
item=index;
|
||||
} else {
|
||||
item=depthStack[j];
|
||||
}
|
||||
|
||||
if (selectedUserPreset[j]!=item) {
|
||||
isSelected=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::PushID(index+1);
|
||||
if (ImGui::Selectable(i.name.c_str(),isSelected)) {
|
||||
selectedUserPreset=depthStack;
|
||||
selectedUserPreset.push_back(index);
|
||||
}
|
||||
ImGui::PopID();
|
||||
if (!i.subDefs.empty()) {
|
||||
depthStack.push_back(index);
|
||||
ImGui::PushID(index);
|
||||
printPresets(i.subDefs,depth+1,depthStack);
|
||||
ImGui::PopID();
|
||||
depthStack.pop_back();
|
||||
}
|
||||
index++;
|
||||
}
|
||||
if (depth>0) ImGui::Unindent();
|
||||
}
|
||||
|
||||
FurnaceGUISysDef* FurnaceGUI::selectPreset(std::vector<FurnaceGUISysDef>& items) {
|
||||
FurnaceGUISysDef* ret=NULL;
|
||||
for (size_t i=0; i<selectedUserPreset.size(); i++) {
|
||||
if (selectedUserPreset[i]<0 || selectedUserPreset[i]>=(int)items.size()) return NULL;
|
||||
ret=&items[selectedUserPreset[i]];
|
||||
if (i<selectedUserPreset.size()-1) {
|
||||
items=ret->subDefs;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FurnaceGUI::drawUserPresets() {
|
||||
if (nextWindow==GUI_WINDOW_USER_PRESETS) {
|
||||
userPresetsOpen=true;
|
||||
ImGui::SetNextWindowFocus();
|
||||
nextWindow=GUI_WINDOW_NOTHING;
|
||||
}
|
||||
if (!userPresetsOpen) return;
|
||||
if (ImGui::Begin("User Systems",&userPresetsOpen,globalWinFlags,_("User Systems"))) {
|
||||
FurnaceGUISysCategory* userCategory=NULL;
|
||||
for (FurnaceGUISysCategory& i: sysCategories) {
|
||||
if (strcmp(i.name,"User")==0) {
|
||||
userCategory=&i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> depthStack;
|
||||
|
||||
if (userCategory==NULL) {
|
||||
ImGui::Text(_("Error! User category does not exist!"));
|
||||
} else if (ImGui::BeginTable("UserPresets",2,ImGuiTableFlags_BordersInnerV,ImVec2(ImGui::GetContentRegionAvail().x,ImGui::GetContentRegionAvail().y-ImGui::GetFrameHeightWithSpacing()))) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.25f);
|
||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.75f);
|
||||
// preset list
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::BeginChild("UList",ImVec2(ImGui::GetContentRegionAvail().x,ImGui::GetContentRegionAvail().y-ImGui::GetFrameHeightWithSpacing()))) {
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text(_("Systems"));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_PLUS "##AddPreset")) {
|
||||
userCategory->systems.push_back(FurnaceGUISysDef(_("New Preset"),{}));
|
||||
selectedUserPreset.clear();
|
||||
selectedUserPreset.push_back(userCategory->systems.size()-1);
|
||||
}
|
||||
printPresets(userCategory->systems,0,depthStack);
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
// editor
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::BeginChild("UEdit",ImVec2(ImGui::GetContentRegionAvail().x,ImGui::GetContentRegionAvail().y-ImGui::GetFrameHeightWithSpacing()))) {
|
||||
if (selectedUserPreset.empty()) {
|
||||
ImGui::Text(_("select a preset"));
|
||||
} else {
|
||||
FurnaceGUISysDef* preset=selectPreset(userCategory->systems);
|
||||
bool doRemovePreset=false;
|
||||
|
||||
if (preset!=NULL) {
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text(_("Name"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-ImGui::CalcTextSize(_("Remove")).x-ImGui::GetStyle().ItemSpacing.x*2.0-ImGui::GetStyle().ItemInnerSpacing.x*2.0);
|
||||
ImGui::InputText("##PName",&preset->name);
|
||||
ImGui::SameLine();
|
||||
pushDestColor();
|
||||
if (ImGui::Button(_("Remove##UPresetRemove"))) {
|
||||
doRemovePreset=true;
|
||||
}
|
||||
popDestColor();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
int doRemove=-1;
|
||||
bool mustBake=false;
|
||||
|
||||
for (size_t i=0; i<preset->orig.size(); i++) {
|
||||
String tempID;
|
||||
FurnaceGUISysDefChip& chip=preset->orig[i];
|
||||
|
||||
bool doInvert=(chip.vol<0);
|
||||
float vol=fabs(chip.vol);
|
||||
ImGui::PushID(i);
|
||||
|
||||
tempID=fmt::sprintf("%s##USystem",getSystemName(chip.sys));
|
||||
ImGui::Button(tempID.c_str(),ImVec2(ImGui::GetContentRegionAvail().x-ImGui::CalcTextSize(_("Invert")).x-ImGui::GetFrameHeightWithSpacing()*2.0-ImGui::GetStyle().ItemSpacing.x*2.0,0));
|
||||
if (ImGui::BeginPopupContextItem("SysPickerCU",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
DivSystem picked=systemPicker();
|
||||
if (picked!=DIV_SYSTEM_NULL) {
|
||||
chip.sys=picked;
|
||||
mustBake=true;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Checkbox(_("Invert"),&doInvert)) {
|
||||
chip.vol=-chip.vol;
|
||||
mustBake=true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
pushDestColor();
|
||||
if (ImGui::Button(ICON_FA_MINUS "##USysRemove")) {
|
||||
doRemove=i;
|
||||
mustBake=true;
|
||||
}
|
||||
popDestColor();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-ImGui::GetFrameHeightWithSpacing()*2.0-ImGui::GetStyle().ItemSpacing.x*2.0);
|
||||
if (CWSliderFloat(_("Volume"),&vol,0.0f,3.0f)) {
|
||||
if (doInvert) {
|
||||
if (vol<0.0001) vol=0.0001;
|
||||
}
|
||||
if (vol<0) vol=0;
|
||||
if (vol>10) vol=10;
|
||||
chip.vol=doInvert?-vol:vol;
|
||||
mustBake=true;
|
||||
} rightClickable
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-ImGui::GetFrameHeightWithSpacing()*2.0-ImGui::GetStyle().ItemSpacing.x*2.0);
|
||||
if (CWSliderFloat(_("Panning"),&chip.pan,-1.0f,1.0f)) {
|
||||
if (chip.pan<-1.0f) chip.pan=-1.0f;
|
||||
if (chip.pan>1.0f) chip.pan=1.0f;
|
||||
mustBake=true;
|
||||
} rightClickable
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-ImGui::GetFrameHeightWithSpacing()*2.0-ImGui::GetStyle().ItemSpacing.x*2.0);
|
||||
if (CWSliderFloat(_("Front/Rear"),&chip.panFR,-1.0f,1.0f)) {
|
||||
if (chip.panFR<-1.0f) chip.panFR=-1.0f;
|
||||
if (chip.panFR>1.0f) chip.panFR=1.0f;
|
||||
mustBake=true;
|
||||
} rightClickable
|
||||
|
||||
if (ImGui::TreeNode(_("Configure"))) {
|
||||
DivConfig sysFlags;
|
||||
sysFlags.loadFromMemory(chip.flags.c_str());
|
||||
if (drawSysConf(-1,i,chip.sys,sysFlags,false)) {
|
||||
chip.flags=sysFlags.toString();
|
||||
mustBake=true;
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
if (doRemove>=0) {
|
||||
preset->orig.erase(preset->orig.begin()+doRemove);
|
||||
mustBake=true;
|
||||
}
|
||||
|
||||
ImGui::Button(ICON_FA_PLUS "##SysAddU");
|
||||
if (ImGui::BeginPopupContextItem("SysPickerU",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
DivSystem picked=systemPicker();
|
||||
if (picked!=DIV_SYSTEM_NULL) {
|
||||
preset->orig.push_back(FurnaceGUISysDefChip(picked,1.0f,0.0f,""));
|
||||
mustBake=true;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Text(_("Advanced"));
|
||||
if (ImGui::InputTextMultiline("##UExtra",&preset->extra,ImVec2(ImGui::GetContentRegionAvail().x,120.0f*dpiScale),ImGuiInputTextFlags_UndoRedo)) {
|
||||
mustBake=true;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip(_(
|
||||
"insert additional settings in `option=value` format.\n"
|
||||
"available options:\n"
|
||||
"- tickRate"
|
||||
));
|
||||
}
|
||||
|
||||
if (mustBake) preset->bake();
|
||||
} else {
|
||||
selectedUserPreset.clear();
|
||||
}
|
||||
|
||||
if (doRemovePreset) {
|
||||
std::vector<FurnaceGUISysDef>& items=userCategory->systems;
|
||||
FurnaceGUISysDef* target=NULL;
|
||||
for (size_t i=0; i<selectedUserPreset.size(); i++) {
|
||||
if (selectedUserPreset[i]<0 || selectedUserPreset[i]>(int)items.size()) break;
|
||||
target=&items[selectedUserPreset[i]];
|
||||
if (i<selectedUserPreset.size()-1) {
|
||||
items=target->subDefs;
|
||||
} else {
|
||||
items.erase(items.begin()+selectedUserPreset[i]);
|
||||
}
|
||||
}
|
||||
|
||||
selectedUserPreset.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if (ImGui::Button(_("Save and Close"))) {
|
||||
userPresetsOpen=false;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Dummy(ImVec2(8.0f*dpiScale,1.0f));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(_("Import"))) {
|
||||
openFileDialog(GUI_FILE_IMPORT_USER_PRESETS);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(_("Import (replace)"))) {
|
||||
openFileDialog(GUI_FILE_IMPORT_USER_PRESETS_REPLACE);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(_("Export"))) {
|
||||
openFileDialog(GUI_FILE_EXPORT_USER_PRESETS);
|
||||
}
|
||||
}
|
||||
if (!userPresetsOpen) {
|
||||
saveUserPresets(true);
|
||||
}
|
||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_USER_PRESETS;
|
||||
ImGui::End();
|
||||
}
|
||||
|
|
@ -90,23 +90,23 @@ String getKeyName(int key, bool emptyNone) {
|
|||
if (emptyNone) {
|
||||
return "";
|
||||
} else {
|
||||
return "<nothing>";
|
||||
return _("<nothing>");
|
||||
}
|
||||
}
|
||||
String ret;
|
||||
if (key&FURKMOD_CTRL) ret+="Ctrl-";
|
||||
if (key&FURKMOD_CTRL) ret+=_("Ctrl-");
|
||||
if (key&FURKMOD_META) ret+=META_MODIFIER_NAME;
|
||||
if (key&FURKMOD_ALT) ret+="Alt-";
|
||||
if (key&FURKMOD_SHIFT) ret+="Shift-";
|
||||
if (key&FURKMOD_ALT) ret+=_("Alt-");
|
||||
if (key&FURKMOD_SHIFT) ret+=_("Shift-");
|
||||
if ((key&FURK_MASK)==0xffffff) {
|
||||
ret+="...";
|
||||
return ret;
|
||||
}
|
||||
const char* name=SDL_GetKeyName(key&FURK_MASK);
|
||||
if (name==NULL) {
|
||||
ret+="Unknown";
|
||||
ret+=_("Unknown");
|
||||
} else if (name[0]==0) {
|
||||
ret+="Unknown";
|
||||
ret+=_("Unknown");
|
||||
} else {
|
||||
ret+=name;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ void FurnaceGUI::drawVolMeter() {
|
|||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,ImVec2(0,0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,ImVec2(0,0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing,ImVec2(0,0));
|
||||
if (ImGui::Begin("Volume Meter",&volMeterOpen,globalWinFlags)) {
|
||||
if (ImGui::Begin("Volume Meter",&volMeterOpen,globalWinFlags,_("Volume Meter"))) {
|
||||
ImDrawList* dl=ImGui::GetWindowDrawList();
|
||||
bool aspectRatio=(ImGui::GetWindowSize().x/ImGui::GetWindowSize().y)>1.0;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,17 +27,17 @@
|
|||
#include <imgui.h>
|
||||
|
||||
const char* waveGenBaseShapes[4]={
|
||||
"Sine",
|
||||
"Triangle",
|
||||
"Saw",
|
||||
"Pulse"
|
||||
_N("Sine"),
|
||||
_N("Triangle"),
|
||||
_N("Saw"),
|
||||
_N("Pulse")
|
||||
};
|
||||
|
||||
const char* waveInterpolations[4]={
|
||||
"None",
|
||||
"Linear",
|
||||
"Cosine",
|
||||
"Cubic"
|
||||
_N("None"),
|
||||
_N("Linear"),
|
||||
_N("Cosine"),
|
||||
_N("Cubic")
|
||||
};
|
||||
|
||||
double sinus(double x) {
|
||||
|
|
@ -189,44 +189,44 @@ WaveFunc waveFuncs[]={
|
|||
};
|
||||
|
||||
const char* fmWaveforms[] = {
|
||||
"Sine",
|
||||
"Rect. Sine",
|
||||
"Abs. Sine",
|
||||
"Quart. Sine",
|
||||
"Squish. Sine",
|
||||
"Abs. Squish. Sine",
|
||||
_N("Sine"),
|
||||
_N("Rect. Sine"),
|
||||
_N("Abs. Sine"),
|
||||
_N("Quart. Sine"),
|
||||
_N("Squish. Sine"),
|
||||
_N("Abs. Squish. Sine"),
|
||||
|
||||
"Square",
|
||||
"rectSquare",
|
||||
_N("Square"),
|
||||
_N("rectSquare"),
|
||||
|
||||
"Saw",
|
||||
"Rect. Saw",
|
||||
"Abs. Saw",
|
||||
_N("Saw"),
|
||||
_N("Rect. Saw"),
|
||||
_N("Abs. Saw"),
|
||||
|
||||
"Cubed Saw",
|
||||
"Rect. Cubed Saw",
|
||||
"Abs. Cubed Saw",
|
||||
_N("Cubed Saw"),
|
||||
_N("Rect. Cubed Saw"),
|
||||
_N("Abs. Cubed Saw"),
|
||||
|
||||
"Cubed Sine",
|
||||
"Rect. Cubed Sine",
|
||||
"Abs. Cubed Sine",
|
||||
"Quart. Cubed Sine",
|
||||
"Squish. Cubed Sine",
|
||||
"Squish. Abs. Cub. Sine",
|
||||
_N("Cubed Sine"),
|
||||
_N("Rect. Cubed Sine"),
|
||||
_N("Abs. Cubed Sine"),
|
||||
_N("Quart. Cubed Sine"),
|
||||
_N("Squish. Cubed Sine"),
|
||||
_N("Squish. Abs. Cub. Sine"),
|
||||
|
||||
"Triangle",
|
||||
"Rect. Triangle",
|
||||
"Abs. Triangle",
|
||||
"Quart. Triangle",
|
||||
"Squish. Triangle",
|
||||
"Abs. Squish. Triangle",
|
||||
_N("Triangle"),
|
||||
_N("Rect. Triangle"),
|
||||
_N("Abs. Triangle"),
|
||||
_N("Quart. Triangle"),
|
||||
_N("Squish. Triangle"),
|
||||
_N("Abs. Squish. Triangle"),
|
||||
|
||||
"Cubed Triangle",
|
||||
"Rect. Cubed Triangle",
|
||||
"Abs. Cubed Triangle",
|
||||
"Quart. Cubed Triangle",
|
||||
"Squish. Cubed Triangle",
|
||||
"Squish. Abs. Cub. Triangle",
|
||||
_N("Cubed Triangle"),
|
||||
_N("Rect. Cubed Triangle"),
|
||||
_N("Abs. Cubed Triangle"),
|
||||
_N("Quart. Cubed Triangle"),
|
||||
_N("Squish. Cubed Triangle"),
|
||||
_N("Squish. Abs. Cub. Triangle"),
|
||||
};
|
||||
|
||||
const size_t fmWaveformsLen=sizeof(fmWaveforms)/sizeof(fmWaveforms[0]);
|
||||
|
|
@ -406,11 +406,11 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
} else {
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(300.0f*dpiScale,300.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||
}
|
||||
if (ImGui::Begin("Wavetable Editor",&waveEditOpen,globalWinFlags|(settings.allowEditDocking?0:ImGuiWindowFlags_NoDocking))) {
|
||||
if (ImGui::Begin("Wavetable Editor",&waveEditOpen,globalWinFlags|(settings.allowEditDocking?0:ImGuiWindowFlags_NoDocking),_("Wavetable Editor"))) {
|
||||
if (curWave<0 || curWave>=(int)e->song.wave.size()) {
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY()+(ImGui::GetContentRegionAvail().y-ImGui::GetFrameHeightWithSpacing()*2.0f)*0.5f);
|
||||
CENTER_TEXT("no wavetable selected");
|
||||
ImGui::Text("no wavetable selected");
|
||||
CENTER_TEXT(_("no wavetable selected"));
|
||||
ImGui::Text(_("no wavetable selected"));
|
||||
if (ImGui::BeginTable("noAssetCenter",3)) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.5f);
|
||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed);
|
||||
|
|
@ -421,7 +421,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
ImGui::TableNextColumn();
|
||||
|
||||
if (e->song.wave.size()>0) {
|
||||
if (ImGui::BeginCombo("##WaveSelect","select one...")) {
|
||||
if (ImGui::BeginCombo("##WaveSelect",_("select one..."))) {
|
||||
if (ImGui::BeginTable("WaveSelCombo",1,ImGuiTableFlags_ScrollY)) {
|
||||
actualWaveList();
|
||||
ImGui::EndTable();
|
||||
|
|
@ -429,16 +429,16 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::TextUnformatted("or");
|
||||
ImGui::TextUnformatted(_("or"));
|
||||
ImGui::SameLine();
|
||||
}
|
||||
if (ImGui::Button("Open")) {
|
||||
if (ImGui::Button(_("Open"))) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_OPEN);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::TextUnformatted("or");
|
||||
ImGui::TextUnformatted(_("or"));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Create New")) {
|
||||
if (ImGui::Button(_("Create New"))) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_ADD);
|
||||
}
|
||||
|
||||
|
|
@ -464,38 +464,38 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
doAction(GUI_ACTION_WAVE_LIST_OPEN_REPLACE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Open");
|
||||
ImGui::SetTooltip(_("Open"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_FLOPPY_O "##WESave")) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_SAVE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Save");
|
||||
ImGui::SetTooltip(_("Save"));
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("WaveSaveFormats",ImGuiMouseButton_Right)) {
|
||||
if (ImGui::MenuItem("save as .dmw...")) {
|
||||
if (ImGui::MenuItem(_("save as .dmw..."))) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_SAVE_DMW);
|
||||
}
|
||||
if (ImGui::MenuItem("save raw...")) {
|
||||
if (ImGui::MenuItem(_("save raw..."))) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_SAVE_RAW);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::RadioButton("Steps",waveEditStyle==0)) {
|
||||
if (ImGui::RadioButton(_("Steps"),waveEditStyle==0)) {
|
||||
waveEditStyle=0;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Lines",waveEditStyle==1)) {
|
||||
if (ImGui::RadioButton(_("Lines"),waveEditStyle==1)) {
|
||||
waveEditStyle=1;
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Width");
|
||||
ImGui::Text(_("Width"));
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("use a width of:\n- any on Amiga/N163\n- 32 on Game Boy, PC Engine, SCC, Konami Bubble System, Namco WSG, Virtual Boy and WonderSwan\n- 64 on FDS\n- 128 on X1-010\nany other widths will be scaled during playback.");
|
||||
ImGui::SetTooltip(_("use a width of:\n- any on Amiga/N163\n- 32 on Game Boy, PC Engine, SCC, Konami Bubble System, Namco WSG, Virtual Boy and WonderSwan\n- 64 on FDS\n- 128 on X1-010\nany other widths will be scaled during playback."));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(96.0f*dpiScale);
|
||||
|
|
@ -507,9 +507,9 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
MARK_MODIFIED;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("Height");
|
||||
ImGui::Text(_("Height"));
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("use a height of:\n- 16 for Game Boy, WonderSwan, Namco WSG, Konami Bubble System, X1-010 Envelope shape and N163\n- 32 for PC Engine\n- 64 for FDS and Virtual Boy\n- 256 for X1-010 and SCC\nany other heights will be scaled during playback.");
|
||||
ImGui::SetTooltip(_("use a height of:\n- 16 for Game Boy, WonderSwan, Namco WSG, Konami Bubble System, X1-010 Envelope shape and N163\n- 32 for PC Engine\n- 64 for FDS and Virtual Boy\n- 256 for X1-010 and SCC\nany other heights will be scaled during playback."));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(96.0f*dpiScale);
|
||||
|
|
@ -575,13 +575,13 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
waveGenSize.y=contentRegion.y;
|
||||
if (ImGui::BeginChild("WaveGenView",waveGenSize)) {
|
||||
if (ImGui::BeginTabBar("WaveGenOpt")) {
|
||||
if (ImGui::BeginTabItem("Shapes")) {
|
||||
if (ImGui::BeginTabItem(_("Shapes"))) {
|
||||
waveGenFM=false;
|
||||
|
||||
if (waveGenBaseShape<0) waveGenBaseShape=0;
|
||||
if (waveGenBaseShape>3) waveGenBaseShape=3;
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (CWSliderInt("##WGShape",&waveGenBaseShape,0,3,waveGenBaseShapes[waveGenBaseShape])) {
|
||||
if (CWSliderInt("##WGShape",&waveGenBaseShape,0,3,_(waveGenBaseShapes[waveGenBaseShape]))) {
|
||||
if (waveGenBaseShape<0) waveGenBaseShape=0;
|
||||
if (waveGenBaseShape>3) waveGenBaseShape=3;
|
||||
doGenerateWave();
|
||||
|
|
@ -594,7 +594,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Duty");
|
||||
ImGui::Text(_("Duty"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (CWSliderFloat("##WGDuty",&waveGenDuty,0.0f,1.0f)) {
|
||||
|
|
@ -604,7 +604,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Exponent");
|
||||
ImGui::Text(_("Exponent"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (CWSliderInt("##WGExp",&waveGenPower,1,8)) {
|
||||
|
|
@ -614,7 +614,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("XOR Point");
|
||||
ImGui::Text(_("XOR Point"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (CWSliderFloat("##WGXOR",&waveGenInvertPoint,0.0f,1.0f)) {
|
||||
|
|
@ -624,7 +624,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if (ImGui::TreeNode("Amplitude/Phase")) {
|
||||
if (ImGui::TreeNode(_("Amplitude/Phase"))) {
|
||||
if (ImGui::BeginTable("WGShapeProps",3)) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.6f);
|
||||
|
|
@ -665,7 +665,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
}
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("FM")) {
|
||||
if (ImGui::BeginTabItem(_("FM"))) {
|
||||
waveGenFM=true;
|
||||
|
||||
if (ImGui::BeginTable("WGFMProps",4)) {
|
||||
|
|
@ -676,13 +676,13 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Op");
|
||||
ImGui::Text(_("Op"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Level");
|
||||
ImGui::Text(_("Level"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Mult");
|
||||
ImGui::Text(_("Mult"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("FB");
|
||||
ImGui::Text(_("FB"));
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
ImGui::TableNextRow();
|
||||
|
|
@ -720,14 +720,14 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
}
|
||||
|
||||
if (ImGui::BeginTable("WGFMWAVE",2)) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,ImGui::CalcTextSize("Op").x);
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,ImGui::CalcTextSize(_("Op")).x);
|
||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,1);
|
||||
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Op");
|
||||
ImGui::Text(_("Op"));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Waveform");
|
||||
ImGui::Text(_("Waveform"));
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
ImGui::TableNextRow();
|
||||
|
|
@ -738,7 +738,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::PushID(i);
|
||||
if (CWSliderInt("##WGWAVEFORM",&fmWaveform[i],0,fmWaveformsLen-1,fmWaveforms[fmWaveform[i]])) {
|
||||
if (CWSliderInt("##WGWAVEFORM",&fmWaveform[i],0,fmWaveformsLen-1,_(fmWaveforms[fmWaveform[i]]))) {
|
||||
doGenerateWave();
|
||||
}
|
||||
ImGui::PopID();
|
||||
|
|
@ -746,8 +746,8 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
CENTER_TEXT("Connection Diagram");
|
||||
ImGui::Text("Connection Diagram");
|
||||
CENTER_TEXT(_("Connection Diagram"));
|
||||
ImGui::Text(_("Connection Diagram"));
|
||||
|
||||
if (ImGui::BeginTable("WGFMCon",6)) {
|
||||
ImGui::TableNextRow();
|
||||
|
|
@ -762,7 +762,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
ImGui::TableNextColumn();
|
||||
ImGui::Text("4");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Out");
|
||||
ImGui::Text(_("Out"));
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
|
@ -869,7 +869,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("WaveTools")) {
|
||||
if (ImGui::BeginTabItem(_("WaveTools"))) {
|
||||
if (ImGui::BeginTable("WGParamItems",2)) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed);
|
||||
|
|
@ -882,18 +882,18 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
if (waveGenScaleX>256) waveGenScaleX=256;
|
||||
}
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (CWSliderInt("##WGInterpolation",&waveInterpolation,0,3,waveInterpolations[waveInterpolation])) {
|
||||
if (CWSliderInt("##WGInterpolation",&waveInterpolation,0,3,_(waveInterpolations[waveInterpolation]))) {
|
||||
if (waveInterpolation<0) waveInterpolation=0;
|
||||
if (waveInterpolation>3) waveInterpolation=3;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Scale X")) {
|
||||
if (ImGui::Button(_("Scale X"))) {
|
||||
if (waveGenScaleX>0 && wave->len!=waveGenScaleX) e->lockEngine([this,wave]() {
|
||||
int origData[256];
|
||||
// Copy original wave to temp buffer
|
||||
// If longer than 256 samples, return
|
||||
if (wave->len>256) {
|
||||
showError("wavetable longer than 256 samples!");
|
||||
showError(_("wavetable longer than 256 samples!"));
|
||||
return;
|
||||
}
|
||||
memcpy(origData,wave->data,wave->len*sizeof(int));
|
||||
|
|
@ -957,7 +957,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
if (waveGenScaleY>256) waveGenScaleY=256;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Scale Y")) {
|
||||
if (ImGui::Button(_("Scale Y"))) {
|
||||
if (waveGenScaleY>0 && wave->max!=(waveGenScaleY-1)) e->lockEngine([this,wave]() {
|
||||
for (int i=0; i<wave->len; i++) {
|
||||
wave->data[i]=(wave->data[i]*(waveGenScaleY))/(wave->max+1);
|
||||
|
|
@ -975,7 +975,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
if (waveGenOffsetX>wave->len-1) waveGenOffsetX=wave->len-1;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Offset X")) {
|
||||
if (ImGui::Button(_("Offset X"))) {
|
||||
if (waveGenOffsetX!=0 && wave->len>0) e->lockEngine([this,wave]() {
|
||||
int origData[256];
|
||||
memcpy(origData,wave->data,wave->len*sizeof(int));
|
||||
|
|
@ -997,7 +997,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
if (waveGenOffsetY>wave->max) waveGenOffsetY=wave->max;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Offset Y")) {
|
||||
if (ImGui::Button(_("Offset Y"))) {
|
||||
if (waveGenOffsetY!=0) e->lockEngine([this,wave]() {
|
||||
for (int i=0; i<wave->len; i++) {
|
||||
wave->data[i]=CLAMP(wave->data[i]+waveGenOffsetY,0,wave->max);
|
||||
|
|
@ -1014,7 +1014,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
if (waveGenSmooth<1) waveGenSmooth=1;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Smooth")) {
|
||||
if (ImGui::Button(_("Smooth"))) {
|
||||
if (waveGenSmooth>0) e->lockEngine([this,wave]() {
|
||||
int origData[256];
|
||||
memcpy(origData,wave->data,wave->len*sizeof(int));
|
||||
|
|
@ -1042,7 +1042,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
if (waveGenAmplify>100.0f) waveGenAmplify=100.0f;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Amplify")) {
|
||||
if (ImGui::Button(_("Amplify"))) {
|
||||
if (waveGenAmplify!=1.0f) e->lockEngine([this,wave]() {
|
||||
for (int i=0; i<wave->len; i++) {
|
||||
wave->data[i]=CLAMP(round((float)(wave->data[i]-(int)( /* Clang can you stop complaining */ (int)(wave->max+1)/(int)2))*waveGenAmplify),(int)(-((wave->max+1)/2)),(int)(wave->max/2))+(int)((wave->max+1)/2);
|
||||
|
|
@ -1060,7 +1060,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
buttonSizeHalf.x-=ImGui::GetStyle().ItemSpacing.x;
|
||||
buttonSizeHalf.x*=0.5;
|
||||
|
||||
if (ImGui::Button("Normalize",buttonSize)) {
|
||||
if (ImGui::Button(_("Normalize"),buttonSize)) {
|
||||
e->lockEngine([this,wave]() {
|
||||
// find lowest point
|
||||
int lowest=wave->max;
|
||||
|
|
@ -1093,7 +1093,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
MARK_MODIFIED;
|
||||
});
|
||||
}
|
||||
if (ImGui::Button("Invert",buttonSizeHalf)) {
|
||||
if (ImGui::Button(_("Invert"),buttonSizeHalf)) {
|
||||
e->lockEngine([this,wave]() {
|
||||
for (int i=0; i<wave->len; i++) {
|
||||
wave->data[i]=wave->max-wave->data[i];
|
||||
|
|
@ -1102,7 +1102,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
});
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Reverse",buttonSizeHalf)) {
|
||||
if (ImGui::Button(_("Reverse"),buttonSizeHalf)) {
|
||||
e->lockEngine([this,wave]() {
|
||||
int origData[256];
|
||||
memcpy(origData,wave->data,wave->len*sizeof(int));
|
||||
|
|
@ -1114,7 +1114,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
});
|
||||
}
|
||||
|
||||
if (ImGui::Button("Half",buttonSizeHalf)) {
|
||||
if (ImGui::Button(_("Half"),buttonSizeHalf)) {
|
||||
int origData[256];
|
||||
memcpy(origData,wave->data,wave->len*sizeof(int));
|
||||
|
||||
|
|
@ -1124,7 +1124,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
MARK_MODIFIED;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Double",buttonSizeHalf)) {
|
||||
if (ImGui::Button(_("Double"),buttonSizeHalf)) {
|
||||
int origData[256];
|
||||
memcpy(origData,wave->data,wave->len*sizeof(int));
|
||||
|
||||
|
|
@ -1134,7 +1134,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
MARK_MODIFIED;
|
||||
}
|
||||
|
||||
if (ImGui::Button("Convert Signed/Unsigned",buttonSize)) {
|
||||
if (ImGui::Button(_("Convert Signed/Unsigned"),buttonSize)) {
|
||||
if (wave->max>0) e->lockEngine([this,wave]() {
|
||||
for (int i=0; i<wave->len; i++) {
|
||||
if (wave->data[i]>(wave->max/2)) {
|
||||
|
|
@ -1146,7 +1146,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
MARK_MODIFIED;
|
||||
});
|
||||
}
|
||||
if (ImGui::Button("Randomize",buttonSize)) {
|
||||
if (ImGui::Button(_("Randomize"),buttonSize)) {
|
||||
if (wave->max>0) e->lockEngine([this,wave]() {
|
||||
for (int i=0; i<wave->len; i++) {
|
||||
wave->data[i]=rand()%(wave->max+1);
|
||||
|
|
@ -1164,11 +1164,11 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if (ImGui::RadioButton("Dec",!waveHex)) {
|
||||
if (ImGui::RadioButton(_("Dec"),!waveHex)) {
|
||||
waveHex=false;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Hex",waveHex)) {
|
||||
if (ImGui::RadioButton(_("Hex"),waveHex)) {
|
||||
waveHex=true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
|
@ -1176,7 +1176,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
waveSigned=!waveSigned;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Signed/Unsigned");
|
||||
ImGui::SetTooltip(_("Signed/Unsigned"));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); // wavetable text input size found here
|
||||
|
|
|
|||
|
|
@ -37,26 +37,26 @@ void FurnaceGUI::drawXYOsc() {
|
|||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,ImVec2(0,0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing,ImVec2(0,0));
|
||||
}
|
||||
if (ImGui::Begin("Oscilloscope (X-Y)",&xyOscOpen,globalWinFlags)) {
|
||||
if (ImGui::Begin("Oscilloscope (X-Y)",&xyOscOpen,globalWinFlags,_("Oscilloscope (X-Y)"))) {
|
||||
if (xyOscOptions) {
|
||||
int xyOscXChannelP1 = xyOscXChannel+1;
|
||||
int xyOscYChannelP1 = xyOscYChannel+1;
|
||||
|
||||
ImGui::Text("X Channel");
|
||||
ImGui::Text(_("X Channel"));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::DragInt("##XChannel",&xyOscXChannelP1,1.0f,1,DIV_MAX_OUTPUTS)) {
|
||||
xyOscXChannel=MIN(MAX(xyOscXChannelP1,1),DIV_MAX_OUTPUTS)-1;
|
||||
} rightClickable
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Invert##X",&xyOscXInvert);
|
||||
ImGui::Text("Y Channel");
|
||||
ImGui::Checkbox(_("Invert##X"),&xyOscXInvert);
|
||||
ImGui::Text(_("Y Channel"));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::DragInt("##YChannel",&xyOscYChannelP1,1.0f,1,DIV_MAX_OUTPUTS)) {
|
||||
xyOscXChannel=MIN(MAX(xyOscYChannelP1,1),DIV_MAX_OUTPUTS)-1;
|
||||
} rightClickable
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Invert##Y",&xyOscYInvert);
|
||||
if (ImGui::SliderFloat("Zoom",&xyOscZoom,0.5f,4.0f,"%.2fx")) {
|
||||
ImGui::Checkbox(_("Invert##Y"),&xyOscYInvert);
|
||||
if (ImGui::SliderFloat(_("Zoom"),&xyOscZoom,0.5f,4.0f,"%.2fx")) {
|
||||
xyOscZoom=MAX(xyOscZoom,0.0f);
|
||||
} rightClickable
|
||||
if (ImGui::IsItemHovered()) {
|
||||
|
|
@ -65,19 +65,19 @@ void FurnaceGUI::drawXYOsc() {
|
|||
if (ImGui::IsItemClicked(ImGuiMouseButton_Middle)) {
|
||||
xyOscZoom=1.0f;
|
||||
}
|
||||
if (ImGui::SliderInt("Samples",&xyOscSamples,2,32768)) {
|
||||
if (ImGui::SliderInt(_("Samples"),&xyOscSamples,2,32768)) {
|
||||
xyOscSamples=MIN(MAX(xyOscSamples,2),32768);
|
||||
} rightClickable
|
||||
if (ImGui::SliderFloat("Decay Time (ms)",&xyOscDecayTime,1.0f,1000.0f,"%.1f",ImGuiSliderFlags_Logarithmic)) {
|
||||
if (ImGui::SliderFloat(_("Decay Time (ms)"),&xyOscDecayTime,1.0f,1000.0f,"%.1f",ImGuiSliderFlags_Logarithmic)) {
|
||||
xyOscDecayTime=MAX(xyOscDecayTime,0.0f);
|
||||
} rightClickable
|
||||
if (ImGui::SliderFloat("Intensity",&xyOscIntensity,0.0f,5.0f,"%.2f")) {
|
||||
if (ImGui::SliderFloat(_("Intensity"),&xyOscIntensity,0.0f,5.0f,"%.2f")) {
|
||||
xyOscIntensity=MAX(xyOscIntensity,0.0f);
|
||||
} rightClickable
|
||||
if (ImGui::SliderFloat("Line Thickness",&xyOscThickness,0.0f,10.0f,"%.2f")) {
|
||||
if (ImGui::SliderFloat(_("Line Thickness"),&xyOscThickness,0.0f,10.0f,"%.2f")) {
|
||||
xyOscThickness=MAX(xyOscThickness,0.0f);
|
||||
} rightClickable
|
||||
if (ImGui::Button("OK")) {
|
||||
if (ImGui::Button(_("OK"))) {
|
||||
xyOscOptions=false;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -210,18 +210,22 @@ void FurnaceGUI::drawXYOsc() {
|
|||
float valX=20.0f*log10f(fabsf((ImGui::GetMousePos().x-inSqrCenter.x)/scaleX));
|
||||
float valY=20.0f*log10f(fabsf((ImGui::GetMousePos().y-inSqrCenter.y)/scaleY));
|
||||
if (valX<=-INFINITY && valY<=-INFINITY) {
|
||||
ImGui::SetTooltip("(-Infinity)dB,(-Infinity)dB");
|
||||
ImGui::SetTooltip(_("(-Infinity)dB,(-Infinity)dB"));
|
||||
} else if (valX<=-INFINITY) {
|
||||
ImGui::SetTooltip("(-Infinity)dB,%.1fdB",valY);
|
||||
ImGui::SetTooltip(_("(-Infinity)dB,%.1fdB"),valY);
|
||||
} else if (valY<=-INFINITY) {
|
||||
ImGui::SetTooltip("%.1fdB,(-Infinity)dB",valY);
|
||||
ImGui::SetTooltip(_("%.1fdB,(-Infinity)dB"),valY);
|
||||
} else {
|
||||
ImGui::SetTooltip("%.1fdB,%.1fdB",valX,valY);
|
||||
ImGui::SetTooltip(_("%.1fdB,%.1fdB"),valX,valY);
|
||||
}
|
||||
}
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
|
||||
xyOscOptions=true;
|
||||
}
|
||||
if (ImGui::IsItemHovered() && CHECK_LONG_HOLD) {
|
||||
NOTIFY_LONG_HOLD;
|
||||
xyOscOptions=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (noPadding) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue