Compare commits
3 Commits
65cd433ac7
...
1c171ed7bd
Author | SHA1 | Date |
---|---|---|
tildearrow | 1c171ed7bd | |
tildearrow | c21f880e3e | |
tildearrow | 4f02f1f90b |
|
@ -66,17 +66,31 @@ settings are saved when clicking the **OK** or **Apply** buttons at the bottom o
|
|||
|
||||
### Output
|
||||
|
||||
- **Backend**: selects SDL or JACK for audio output.
|
||||
- only appears on Linux, or MacOS compiled with JACK support
|
||||
- **Driver**: select a different SDL audio driver if you're having problems with the default one.
|
||||
- **Backend**: selects a different backend for audio output.
|
||||
- SDL: the default one.
|
||||
- JACK: the JACK Audio Connection Kit (low-latency audio server). only appears on Linux, or MacOS compiled with JACK support.
|
||||
- PortAudio: this may or may not perform better than the SDL backend.
|
||||
- **Driver**: select a different audio driver if you're having problems with the default one.
|
||||
- only appears when Backend is SDL.
|
||||
- **Device**: audio device for playback.
|
||||
- **Sample rate**
|
||||
- if using PortAudio backend, devices will be prefixed with the audio API that PortAudio is going to use:
|
||||
- Windows WASAPI: a modern audio API available on Windows Vista and later, featuring an (optional) Exclusive Mode. be noted that your buffer size setting may be ignored.
|
||||
- Windows WDM-KS: low-latency, direct to hardware output mechanism. may not work all the time and prevents your audio device from being used for anything else!
|
||||
- Windows DirectSound: this is the worst choice. best to move on.
|
||||
- MME: an old audio API. doesn't have Exclusive Mode.
|
||||
- Core Audio: the only choice in macOS.
|
||||
- ALSA: low-level audio output on Linux. may prevent other applications from using your audio device.
|
||||
- **Sample rate**: audio output rate.
|
||||
- a lower rate decreases quality and isn't really beneficial.
|
||||
- if using PortAudio backend, be careful about this value.
|
||||
- **Outputs**: number of audio outputs created, up to 16.
|
||||
- only appears when Backend is JACK.
|
||||
- **Channels**: number of output channels to use.
|
||||
- **Channels**: mono, stereo or something.
|
||||
- **Buffer size**: size of buffer in both samples and milliseconds.
|
||||
- setting this to a low value may cause stuttering/glitches in playback (known as "underruns" or "xruns").
|
||||
- setting this to a high value increases latency.
|
||||
- **Exclusive mode**: enables Exclusive Mode, which may offer latency improvements.
|
||||
- only available on WASAPI devices in the PortAudio backend!
|
||||
- **Low-latency mode (experimental!)**: reduces latency by running the engine faster than the tick rate. useful for live playback/jam mode.
|
||||
- only enable if your buffer size is small (10ms or less).
|
||||
- **Force mono audio**: use if you're unable to hear stereo audio (e.g. single speaker or hearing loss in one ear).
|
||||
|
@ -88,6 +102,7 @@ settings are saved when clicking the **OK** or **Apply** buttons at the bottom o
|
|||
- **Quality**: selects quality of resampling. low quality reduces CPU load by a small amount.
|
||||
- **Software clipping**: clips output to nominal range (-1.0 to 1.0) before passing it to the audio device.
|
||||
- this avoids activating Windows' built-in limiter.
|
||||
- this option shall be enabled when using PortAudio backend with a DirectSound device.
|
||||
|
||||
### Metronome
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ const char* aboutLine[]={
|
|||
"Burnt Fishy",
|
||||
"CaptainMalware",
|
||||
"Clingojam",
|
||||
"Crisps",
|
||||
"DeMOSic",
|
||||
"DevEd",
|
||||
"Dippy",
|
||||
|
|
|
@ -76,7 +76,38 @@ void _nfdThread(const NFDState state, std::atomic<bool>* ok, std::vector<String>
|
|||
}
|
||||
#endif
|
||||
|
||||
bool FurnaceGUIFileDialog::openLoad(String header, std::vector<String> filter, const char* noSysFilter, String path, double dpiScale, FileDialogSelectCallback clickCallback, bool allowMultiple) {
|
||||
void FurnaceGUIFileDialog::convertFilterList(std::vector<String>& filter) {
|
||||
memset(noSysFilter,0,4096);
|
||||
|
||||
String result;
|
||||
|
||||
for (size_t i=0; (i+1)<filter.size(); i+=2) {
|
||||
String label=filter[i];
|
||||
String ext;
|
||||
|
||||
if (filter[i+1]=="*") {
|
||||
ext=".*";
|
||||
} else for (char i: filter[i+1]) {
|
||||
switch (i) {
|
||||
case '*':
|
||||
break;
|
||||
case ' ':
|
||||
ext+=',';
|
||||
break;
|
||||
default:
|
||||
ext+=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result.empty()) result+=',';
|
||||
result+=fmt::sprintf("%s{%s}",label,ext);
|
||||
}
|
||||
|
||||
strncpy(noSysFilter,result.c_str(),4095);
|
||||
}
|
||||
|
||||
bool FurnaceGUIFileDialog::openLoad(String header, std::vector<String> filter, String path, double dpiScale, FileDialogSelectCallback clickCallback, bool allowMultiple) {
|
||||
if (opened) return false;
|
||||
saving=false;
|
||||
curPath=path;
|
||||
|
@ -149,6 +180,8 @@ bool FurnaceGUIFileDialog::openLoad(String header, std::vector<String> filter, c
|
|||
}
|
||||
#endif
|
||||
|
||||
convertFilterList(filter);
|
||||
|
||||
ImGuiFileDialog::Instance()->singleClickSel=mobileUI;
|
||||
ImGuiFileDialog::Instance()->DpiScale=dpiScale;
|
||||
ImGuiFileDialog::Instance()->mobileMode=mobileUI;
|
||||
|
@ -159,7 +192,7 @@ bool FurnaceGUIFileDialog::openLoad(String header, std::vector<String> filter, c
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIFileDialog::openSave(String header, std::vector<String> filter, const char* noSysFilter, String path, double dpiScale) {
|
||||
bool FurnaceGUIFileDialog::openSave(String header, std::vector<String> filter, String path, double dpiScale) {
|
||||
if (opened) return false;
|
||||
|
||||
#ifdef ANDROID
|
||||
|
@ -233,6 +266,8 @@ bool FurnaceGUIFileDialog::openSave(String header, std::vector<String> filter, c
|
|||
} else {
|
||||
hasError=false;
|
||||
|
||||
convertFilterList(filter);
|
||||
|
||||
ImGuiFileDialog::Instance()->singleClickSel=false;
|
||||
ImGuiFileDialog::Instance()->DpiScale=dpiScale;
|
||||
ImGuiFileDialog::Instance()->mobileMode=mobileUI;
|
||||
|
|
|
@ -31,6 +31,7 @@ class FurnaceGUIFileDialog {
|
|||
bool opened;
|
||||
bool saving;
|
||||
bool hasError;
|
||||
char noSysFilter[4096];
|
||||
String curPath;
|
||||
std::vector<String> fileName;
|
||||
#ifdef USE_NFD
|
||||
|
@ -46,10 +47,12 @@ class FurnaceGUIFileDialog {
|
|||
pfd::open_file* dialogO;
|
||||
pfd::save_file* dialogS;
|
||||
#endif
|
||||
|
||||
void convertFilterList(std::vector<String>& filter);
|
||||
public:
|
||||
bool mobileUI;
|
||||
bool openLoad(String header, std::vector<String> filter, const char* noSysFilter, String path, double dpiScale, FileDialogSelectCallback clickCallback=NULL, bool allowMultiple=false);
|
||||
bool openSave(String header, std::vector<String> filter, const char* noSysFilter, String path, double dpiScale);
|
||||
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 accepted();
|
||||
void close();
|
||||
bool render(const ImVec2& min, const ImVec2& max);
|
||||
|
|
|
@ -1567,7 +1567,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
"Open File",
|
||||
{"compatible files", "*.fur *.dmf *.mod *.fc13 *.fc14 *.smod *.fc",
|
||||
"all files", "*"},
|
||||
"compatible files{.fur,.dmf,.mod,.fc13,.fc14,.smod,.fc},.*",
|
||||
workingDirSong,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1580,7 +1579,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openLoad(
|
||||
"Restore Backup",
|
||||
{"Furnace song", "*.fur"},
|
||||
"Furnace song{.fur}",
|
||||
backupPath+String(DIR_SEPARATOR_STR),
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1590,7 +1588,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Save File",
|
||||
{"Furnace song", "*.fur"},
|
||||
"Furnace song{.fur}",
|
||||
workingDirSong,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1600,7 +1597,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Save File",
|
||||
{"DefleMask 1.1.3 module", "*.dmf"},
|
||||
"DefleMask 1.1.3 module{.dmf}",
|
||||
workingDirSong,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1610,7 +1606,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Save File",
|
||||
{"DefleMask 1.0/legacy module", "*.dmf"},
|
||||
"DefleMask 1.0/legacy module{.dmf}",
|
||||
workingDirSong,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1627,8 +1622,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
if (!dirExists(workingDirIns)) workingDirIns=getHomeDir();
|
||||
hasOpened=fileDialog->openLoad(
|
||||
"Load Instrument",
|
||||
// TODO supply loadable formats in a dynamic, scalable, "DRY" way.
|
||||
// thank the author of IGFD for making things impossible
|
||||
{"all compatible files", "*.fui *.dmp *.tfi *.vgi *.s3i *.sbi *.opli *.opni *.y12 *.bnk *.ff *.gyb *.opm *.wopl *.wopn",
|
||||
"Furnace instrument", "*.fui",
|
||||
"DefleMask preset", "*.dmp",
|
||||
|
@ -1646,7 +1639,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
"Wohlstand WOPL bank", "*.wopl",
|
||||
"Wohlstand WOPN bank", "*.wopn",
|
||||
"all files", "*"},
|
||||
"all compatible files{.fui,.dmp,.tfi,.vgi,.s3i,.sbi,.opli,.opni,.y12,.bnk,.ff,.gyb,.opm,.wopl,.wopn},.*",
|
||||
workingDirIns,
|
||||
dpiScale,
|
||||
[this](const char* path) {
|
||||
|
@ -1681,7 +1673,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Save Instrument",
|
||||
{"Furnace instrument", "*.fui"},
|
||||
"Furnace instrument{.fui}",
|
||||
workingDirIns,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1691,7 +1682,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Save Instrument",
|
||||
{"DefleMask preset", "*.dmp"},
|
||||
"DefleMask preset{.dmp}",
|
||||
workingDirIns,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1703,7 +1693,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
"Load Wavetable",
|
||||
{"compatible files", "*.fuw *.dmw",
|
||||
"all files", "*"},
|
||||
"compatible files{.fuw,.dmw},.*",
|
||||
workingDirWave,
|
||||
dpiScale,
|
||||
NULL, // TODO
|
||||
|
@ -1715,7 +1704,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Save Wavetable",
|
||||
{"Furnace wavetable", ".fuw"},
|
||||
"Furnace wavetable{.fuw}",
|
||||
workingDirWave,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1725,7 +1713,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Save Wavetable",
|
||||
{"DefleMask wavetable", ".dmw"},
|
||||
"DefleMask wavetable{.dmw}",
|
||||
workingDirWave,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1735,7 +1722,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Save Wavetable",
|
||||
{"raw data", ".raw"},
|
||||
"raw data{.raw}",
|
||||
workingDirWave,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1747,7 +1733,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
"Load Sample",
|
||||
{"compatible files", "*.wav *.dmc *.brr",
|
||||
"all files", "*"},
|
||||
"compatible files{.wav,.dmc,.brr},.*",
|
||||
workingDirSample,
|
||||
dpiScale,
|
||||
NULL, // TODO
|
||||
|
@ -1760,7 +1745,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openLoad(
|
||||
"Load Raw Sample",
|
||||
{"all files", "*"},
|
||||
".*",
|
||||
workingDirSample,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1770,7 +1754,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Save Sample",
|
||||
{"Wave file", "*.wav"},
|
||||
"Wave file{.wav}",
|
||||
workingDirSample,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1778,9 +1761,8 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
case GUI_FILE_SAMPLE_SAVE_RAW:
|
||||
if (!dirExists(workingDirSample)) workingDirSample=getHomeDir();
|
||||
hasOpened=fileDialog->openSave(
|
||||
"Load Raw Sample",
|
||||
"Save Raw Sample",
|
||||
{"all files", "*"},
|
||||
".*",
|
||||
workingDirSample,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1790,7 +1772,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Export Audio",
|
||||
{"Wave file", "*.wav"},
|
||||
"Wave file{.wav}",
|
||||
workingDirAudioExport,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1800,7 +1781,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Export Audio",
|
||||
{"Wave file", "*.wav"},
|
||||
"Wave file{.wav}",
|
||||
workingDirAudioExport,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1810,7 +1790,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Export Audio",
|
||||
{"Wave file", "*.wav"},
|
||||
"Wave file{.wav}",
|
||||
workingDirAudioExport,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1820,7 +1799,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Export VGM",
|
||||
{"VGM file", "*.vgm"},
|
||||
"VGM file{.vgm}",
|
||||
workingDirVGMExport,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1830,7 +1808,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Export ZSM",
|
||||
{"ZSM file", "*.zsm"},
|
||||
"ZSM file{.zsm}",
|
||||
workingDirZSMExport,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1840,7 +1817,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Export Command Stream",
|
||||
{"text file", "*.txt"},
|
||||
"text file{.txt}",
|
||||
workingDirROMExport,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1850,7 +1826,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Export Command Stream",
|
||||
{"binary file", "*.bin"},
|
||||
"binary file{.bin}",
|
||||
workingDirROMExport,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1863,7 +1838,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openLoad(
|
||||
"Select Font",
|
||||
{"compatible files", "*.ttf *.otf *.ttc"},
|
||||
"compatible files{.ttf,.otf,.ttc}",
|
||||
workingDirFont,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1873,7 +1847,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openLoad(
|
||||
"Select Font",
|
||||
{"compatible files", "*.ttf *.otf *.ttc"},
|
||||
"compatible files{.ttf,.otf,.ttc}",
|
||||
workingDirFont,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1883,7 +1856,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openLoad(
|
||||
"Select Font",
|
||||
{"compatible files", "*.ttf *.otf *.ttc"},
|
||||
"compatible files{.ttf,.otf,.ttc}",
|
||||
workingDirFont,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1893,7 +1865,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openLoad(
|
||||
"Select Color File",
|
||||
{"configuration files", "*.cfgc"},
|
||||
"configuration files{.cfgc}",
|
||||
workingDirColors,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1903,7 +1874,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openLoad(
|
||||
"Select Keybind File",
|
||||
{"configuration files", "*.cfgk"},
|
||||
"configuration files{.cfgk}",
|
||||
workingDirKeybinds,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1913,7 +1883,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openLoad(
|
||||
"Select Layout File",
|
||||
{".ini files", "*.ini"},
|
||||
".ini files{.ini}",
|
||||
workingDirKeybinds,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1923,7 +1892,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Export Colors",
|
||||
{"configuration files", "*.cfgc"},
|
||||
"configuration files{.cfgc}",
|
||||
workingDirColors,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1933,7 +1901,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Export Keybinds",
|
||||
{"configuration files", "*.cfgk"},
|
||||
"configuration files{.cfgk}",
|
||||
workingDirKeybinds,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1943,7 +1910,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
hasOpened=fileDialog->openSave(
|
||||
"Export Layout",
|
||||
{".ini files", "*.ini"},
|
||||
".ini files{.ini}",
|
||||
workingDirKeybinds,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1956,7 +1922,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
"Load ROM",
|
||||
{"compatible files", "*.rom *.bin",
|
||||
"all files", "*"},
|
||||
"compatible files{.rom,.bin},.*",
|
||||
workingDirROM,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1967,7 +1932,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
"Play Command Stream",
|
||||
{"command stream", "*.bin",
|
||||
"all files", "*"},
|
||||
"command stream{.bin},.*",
|
||||
workingDirROM,
|
||||
dpiScale
|
||||
);
|
||||
|
@ -1979,7 +1943,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
{"compatible files", "*.fur *.dmf *.mod",
|
||||
"another option", "*.wav *.ttf",
|
||||
"all files", "*"},
|
||||
"compatible files{.fur,.dmf,.mod},another option{.wav,.ttf},.*",
|
||||
workingDirTest,
|
||||
dpiScale,
|
||||
[](const char* path) {
|
||||
|
@ -1998,7 +1961,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
{"compatible files", "*.fur *.dmf *.mod",
|
||||
"another option", "*.wav *.ttf",
|
||||
"all files", "*"},
|
||||
"compatible files{.fur,.dmf,.mod},another option{.wav,.ttf},.*",
|
||||
workingDirTest,
|
||||
dpiScale,
|
||||
[](const char* path) {
|
||||
|
@ -2017,7 +1979,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
"Save Test",
|
||||
{"Furnace song", "*.fur",
|
||||
"DefleMask module", "*.dmf"},
|
||||
"Furnace song{.fur},DefleMask module{.dmf}",
|
||||
workingDirTest,
|
||||
dpiScale
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue