Merge branch 'master' of https://github.com/tildearrow/furnace into k053260
This commit is contained in:
commit
79a082c5d2
|
@ -36,6 +36,7 @@ advanced topics:
|
|||
|
||||
other topics:
|
||||
|
||||
- [settings](../2-interface/settings.md)
|
||||
- [UI components](components.md)
|
||||
- [global keyboard shortcuts](keyboard.md)
|
||||
- [basic mode](basic-mode.md)
|
||||
|
|
|
@ -183,7 +183,7 @@ it's not really useful, unless you're a developer and want to use a command stre
|
|||
- **basic mode**: toggles [Basic Mode](basic-mode.md).
|
||||
- **visualizer**: toggles pattern view particle effects when the song plays.
|
||||
- **reset layout**: resets the workspace to its defaults.
|
||||
- **settings...**: opens the Settings window.
|
||||
- **settings...**: opens the Settings window. these are detailed in [settings.md].
|
||||
|
||||
# window
|
||||
|
||||
|
|
|
@ -0,0 +1,387 @@
|
|||
# settings
|
||||
|
||||
settings are saved when clicking the **OK** button at the bottom of the dialog.
|
||||
|
||||
|
||||
|
||||
# General
|
||||
|
||||
- **Workspace layout**
|
||||
- **Import**: reads a .ini layout file.
|
||||
- **Export**: writes current layout to a .ini file.
|
||||
- **Reset**: resets layout to default.
|
||||
|
||||
- **Initial system**: the system of chips loaded on starting Furnace.
|
||||
- **Current system**: sets current chips as default.
|
||||
- **Randomize**: set default to a random system.
|
||||
- this will not choose a random system at each start.
|
||||
- **Reset to defaults**: sets default to "Sega Genesis/Mega Drive".
|
||||
- **Name**: name for the default system. may be set to any text.
|
||||
- system configuration: same as in the [chip manager](../8-advanced/chip-manager.md) and [mixer](../8-advanced/mixer.md).
|
||||
|
||||
- **Play intro on start-up:**
|
||||
- **No**: skips intro entirely.
|
||||
- **Short**: shows silent title screen briefly.
|
||||
- **Full (short when loading song)**: shows animated musical intro unless started with a song (command line, double-clicking a .fur file, etc.)
|
||||
- **Full (always)**: always shows animated musical intro.
|
||||
- **When creating new song**:
|
||||
- **Display system preset selector**
|
||||
- **Start with initial system**
|
||||
|
||||
- **Double-click time (seconds)**: maximum time between mouse clicks to recognize them as a double-click.
|
||||
- **Toggle channel solo on:** select which interactions with a channel header will toggle solo for that channel.
|
||||
- **Push value when overwriting instead of clearing it**: in the order list and pattern editors, typing into an already-filled value will shift digits instead of starting fresh.
|
||||
- if off: moving the cursor onto the value `A5` and typing a "B" results in `0B`.
|
||||
- if on: with the cursor on the value `A5` and typing a "B" results in `5B`.
|
||||
- **Move cursor up on backspace-delete**
|
||||
- **Move cursor by edit step on delete**
|
||||
- **Change current instrument when changing instrument column (absorb)**
|
||||
- **Delete effect value when deleting effect**
|
||||
- **Change order when scrolling outside of pattern bounds**:
|
||||
- if off, the pattern edit cursor will stay locked within the current order.
|
||||
- if on, moving the cursor past the edge of the previous or next order will move to that order.
|
||||
- **Move cursor by edit step on insert (push)**
|
||||
- **Move cursor to end of clipboard content when pasting**
|
||||
- **Don't scroll when moving cursor**
|
||||
- **Double click selects entire column**
|
||||
- **Allow docking editors**
|
||||
- **Don't raise pattern editor on click**
|
||||
- **Focus pattern editor when selecting instrument**
|
||||
- **Restart song when changing chip properties**
|
||||
- **Use system file picker**: use native OS file dialog instead of Furnace's.
|
||||
- **Only allow window movement when clicking on title bar**
|
||||
- **Enable event delay**
|
||||
- may cause issues with high-polling-rate mice when previewing notes.
|
||||
- **Power-saving mode**
|
||||
- saves power by lowering the frame rate to 2fps when idle.
|
||||
- may cause issues under Mesa drivers!
|
||||
- **Disable threaded input (restart after changing!)**
|
||||
- threaded input processes key presses for note preview on a separate thread (on supported platforms), which reduces latency.
|
||||
- however, crashes have been reported when threaded input is on. enable this option if that is the case.
|
||||
- **Remember window position**
|
||||
- remembers the window's last position on start-up.
|
||||
- **New instruments are blank**
|
||||
- **Save unused patterns**
|
||||
- **Compress when saving**
|
||||
- use zlib to compress saved songs.
|
||||
- **Cursor follows current order when moving it**
|
||||
- applies when playback is stopped.
|
||||
- **Audio export loop/fade out time:**
|
||||
- **Set to these values on start-up:**
|
||||
- **Loops**: number of additional times to play through `0Bxx` song loop.
|
||||
- **Fade out (seconds)**: length of fade out after final loop.
|
||||
- **Remember last values**
|
||||
- **Note preview behavior:**
|
||||
- **Never**
|
||||
- **When cursor is in Note column**
|
||||
- **When cursor is in Note column or not in edit mode**
|
||||
- **Always**
|
||||
- **Wrap pattern cursor horizontally:**
|
||||
- **No**
|
||||
- **Yes**
|
||||
- **Yes, and move to next/prev row**
|
||||
- **Wrap pattern cursor vertically:**
|
||||
- **No**
|
||||
- **Yes**
|
||||
- **Yes, and move to next/prev pattern**
|
||||
- **Cursor movement keys behavior:**
|
||||
- **Move by one**
|
||||
- **Move by Edit Step**
|
||||
- **Effect input cursor behavior:**
|
||||
- **Move down**
|
||||
- **Move to effect value (otherwise move down)**
|
||||
- **Move to effect value/next effect and wrap around**
|
||||
- **Allow dragging selection:**
|
||||
- **No**
|
||||
- **Yes**
|
||||
- **Yes (while holding Ctrl only)**
|
||||
|
||||
|
||||
|
||||
# Audio/MIDI
|
||||
|
||||
- **Backend**: select SDL or JACK for audio output.
|
||||
- only appears on Linux, or MacOS compiled with JACK support
|
||||
- **Device**: audio device for playback.
|
||||
- **Sample rate**
|
||||
- **Outputs**: select number of audio outputs created, up to 16.
|
||||
- only appears when Backend is JACK.
|
||||
- **Channels**: number of output channels to use.
|
||||
- **Buffer size**: size of buffer in both samples and milliseconds.
|
||||
- **Quality**: selects quality of resampling. low quality reduces CPU load.
|
||||
- **Metronome volume**
|
||||
- **Low-latency mode (experimental!)**: reduces latency by running the engine faster than the tick rate. useful for live playback/jam mode.
|
||||
- _warning:_ experimental! may produce glitches. only enable if your buffer size is small (10ms or less).
|
||||
- **Force mono audio**
|
||||
- **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.
|
||||
- **want:** displays requested audio configuration.
|
||||
- **got:** displays actual audio configuration returned by audio backend.
|
||||
|
||||
- **MIDI input**
|
||||
- **MIDI output**
|
||||
- **MIDI input settings**
|
||||
- **Note input**
|
||||
- **Velocity input**
|
||||
- **Map MIDI channels to direct channels**
|
||||
- **Map Yamaha FM voice data to instruments**
|
||||
- **Program change is instrument selection**
|
||||
- **Value input style**:
|
||||
- **Disabled/custom**
|
||||
- **Two octaves (0 is C-4, F is D#5)**
|
||||
- **Raw (note number is value)**
|
||||
- **Two octaves alternate (lower keys are 0-9, upper keys are A-F)**
|
||||
- **Use dual control change (one for each nibble)**
|
||||
- **CC of upper nibble**
|
||||
- **CC of lower nibble**
|
||||
- **Use 14-bit control change**
|
||||
- **MSB CC**
|
||||
- **LSB CC**
|
||||
- **Use single control change**
|
||||
- **Control**
|
||||
- **Per-column control change**
|
||||
- **Instrument**\
|
||||
**Volume**\
|
||||
**Effect `x` type**\
|
||||
**Effect `x` value**
|
||||
- **Disabled/custom**
|
||||
- **Use dual control change (one for each nibble)**
|
||||
- **CC of upper nibble**
|
||||
- **CC of lower nibble**
|
||||
- **Use 14-bit control change**
|
||||
- **MSB CC**
|
||||
- **LSB CC**
|
||||
- **Use single control change (imprecise)**
|
||||
- **Control**
|
||||
- **Volume curve**
|
||||
- **Actions:**
|
||||
- **`+`** button: adds a new action.
|
||||
- window-with-arrow button: new action with learning! press a button or move a slider/knob/something on your device.
|
||||
- each action has the following:
|
||||
- **Type**
|
||||
- **Channel**
|
||||
- **Note/Control**
|
||||
- **Velocity/Value**
|
||||
- **Action**
|
||||
- **Learn**
|
||||
- **Remove**
|
||||
|
||||
- **MIDI output settings**
|
||||
- **Output mode:**
|
||||
- **Off (use for TX81Z)**
|
||||
- **Melodic**
|
||||
- **Send Program Change**
|
||||
- **Send MIDI clock**
|
||||
- **Send MIDI timecode**
|
||||
- **Timecode frame rate:**
|
||||
- **Closest to Tick Rate**
|
||||
- **Film (24fps)**
|
||||
- **PAL (25fps)**
|
||||
- **NTSC drop (29.97fps)**
|
||||
- **NTSC non-drop (30fps)**
|
||||
|
||||
# Emulation
|
||||
- **Arcade/YM2151 core**
|
||||
- **ymfm**
|
||||
- **Nuked-OPM**
|
||||
- **Genesis/YM2612 core**
|
||||
- **Nuked-OPN2**
|
||||
- **ymfm**
|
||||
- **SN76489 core**
|
||||
- **MAME**
|
||||
- **Nuked-PSG Mod**
|
||||
- **NES core**
|
||||
- **puNES**
|
||||
- **NSFplay**
|
||||
- **FDS core**
|
||||
- **puNES**
|
||||
- **NSFplay**
|
||||
- **SID core**
|
||||
- **reSID**
|
||||
- **reSIDfp**
|
||||
- **POKEY core**
|
||||
- **Atari800 (mzpokeysnd)**
|
||||
- **ASAP (C++ port)**
|
||||
- **OPN/OPNA/OPNB cores**
|
||||
- **ymfm only**
|
||||
- **Nuked-OPN2 (FM) + ymfm (SSG/ADPCM)**
|
||||
|
||||
- **PC Speaker strategy:**
|
||||
- **evdev SND_TONE**
|
||||
- **KIOCSOUND on /dev/tty1**
|
||||
- **/dev/port**
|
||||
- **KIOCSOUND on standard output**
|
||||
- **outb()**
|
||||
|
||||
- **Sample ROMs:**
|
||||
- **OPL4 YRW801 path**
|
||||
- **MultiPCM TG100 path**
|
||||
- **MultiPCM MU5 path**
|
||||
|
||||
|
||||
|
||||
# Appearance
|
||||
|
||||
- **Render driver**
|
||||
- **Automatic UI scaling factor**: automatically match the OS's UI scaling.
|
||||
- **UI scaling factor**: only if "Automatic UI scaling factor" is off.
|
||||
- **Main font**: if "Custom...", a file path selector will appear beneath.
|
||||
- **Size**
|
||||
- **Pattern font**: if "Custom...", a file path selector will appear beneath.
|
||||
- **Size**
|
||||
- **Icon size**
|
||||
- **Display Japanese characters**\
|
||||
**Display Chinese (Simplified) characters**\
|
||||
**Display Chinese (Traditional) characters**\
|
||||
**Display Korean characters**
|
||||
- only toggle these options if you have enough graphics memory.
|
||||
- these are a temporary solution until dynamic font atlas is implemented in Dear ImGui.
|
||||
|
||||
- **Number of recent files**
|
||||
|
||||
- **Pattern view labels:**
|
||||
- **Note off (3-char)**: default is `OFF`
|
||||
- **Note release (3-char)**: default is `===`.
|
||||
- **Macro release (3-char)**: default is `REL`.
|
||||
- **Empty field (3-char)**: default is `...`.
|
||||
- **Empty field (2-char)**: default is `..`.
|
||||
|
||||
- **Orders row number format:**
|
||||
- **Decimal**
|
||||
- **Hexadecimal**
|
||||
- **Pattern row number format:**
|
||||
- **Decimal**
|
||||
- **Hexadecimal**
|
||||
- **FM parameter names:**
|
||||
- **Friendly**
|
||||
- **Technical**
|
||||
- **Technical (alternate)**
|
||||
|
||||
- **Title bar:**
|
||||
- **Furnace**
|
||||
- **Song Name - Furnace**
|
||||
- **file_name.fur - Furnace**
|
||||
- **/path/to/file.fur - Furnace**
|
||||
- **Display system name on title bar**
|
||||
- **Display chip names instead of "multi-system" in title bar**
|
||||
- **Status bar:**
|
||||
- **Cursor details**
|
||||
- **File path**
|
||||
- **Cursor details or file path**
|
||||
- **Nothing**
|
||||
- **Play/edit controls layout:**
|
||||
- **Classic**
|
||||
- **Compact**
|
||||
- **Compact (vertical)**
|
||||
- **Split**
|
||||
- **Position of buttons in Orders:**
|
||||
- **Top**
|
||||
- **Left**
|
||||
- **Right**
|
||||
- **FM parameter editor layout:**
|
||||
- **Modern**
|
||||
- **Compact (2x2, classic)**
|
||||
- **Compact (1x4)**
|
||||
- **Compact (4x1)**
|
||||
- **Alternate (2x2)**
|
||||
- **Alternate (1x4)**
|
||||
- **Alternate (4x1)**
|
||||
- **Position of Sustain in FM editor:**
|
||||
- **Between Decay and Sustain Rate**
|
||||
- **After Release Rate**
|
||||
- **Macro editor layout:**
|
||||
- **Unified**
|
||||
- **Mobile**
|
||||
- **Grid**
|
||||
- **Single (with list)**
|
||||
- **Single (combo box)**
|
||||
|
||||
- **Namco 163 chip name**
|
||||
|
||||
- **Channel colors:**
|
||||
- **Single**
|
||||
- **Channel type**
|
||||
- **Instrument type**
|
||||
- **Channel name colors:**
|
||||
- **Single**
|
||||
- **Channel type**
|
||||
- **Instrument type**
|
||||
- **Channel style:**
|
||||
- **Classic**
|
||||
- **Line**
|
||||
- **Round**
|
||||
- **Split button**
|
||||
- **Square border**
|
||||
- **Round border**
|
||||
- **Channel volume bar:**
|
||||
- **None**
|
||||
- **Simple**
|
||||
- **Stereo**
|
||||
- **Real**
|
||||
- **Real (stereo)**
|
||||
- **Channel feedback style:**
|
||||
- **Off**
|
||||
- **Note**
|
||||
- **Volume**
|
||||
- **Active**
|
||||
- **Channel font:**
|
||||
- **Regular**
|
||||
- **Monospace**
|
||||
- **Center channel name**
|
||||
|
||||
- **Colorize instrument editor using instrument type**
|
||||
- **Use separate colors for carriers/modulators in FM editor**
|
||||
- **Unified instrument/wavetable/sample list**
|
||||
- **Horizontal instrument list**
|
||||
- **Use standard OPL waveform names**
|
||||
- **Overflow pattern highlights**
|
||||
- **Display previous/next pattern**
|
||||
- **Use German notation**: display `B` notes as `H`, and `A#` notes as `B`.
|
||||
- **Single-digit effects for 00-0F**
|
||||
- **Center pattern view**: centers pattern horizontally in view.
|
||||
- **Unsigned FM detune values**
|
||||
- **Highlight channel at cursor in Orders**
|
||||
- **About screen party time**
|
||||
- _warning:_ may cause epileptic seizures.
|
||||
|
||||
- **Use compact wave editor**
|
||||
- **Use classic macro editor vertical slider**
|
||||
- **Rounded window corners**
|
||||
- **Rounded buttons**
|
||||
- **Rounded menu corners**
|
||||
- **Borders around widgets**
|
||||
- **Disable fade-in during start-up**
|
||||
|
||||
- **Oscilloscope settings:**
|
||||
- **Rounded corners**
|
||||
- **Fill entire window**
|
||||
- **Waveform goes out of bounds**
|
||||
- **Border**
|
||||
|
||||
- **Pattern view spacing after:**
|
||||
- **Note**
|
||||
- **Instrument**
|
||||
- **Volume**
|
||||
- **Effect**
|
||||
- **Effect value**
|
||||
- **Color scheme**
|
||||
- **Import**
|
||||
- **Export**
|
||||
- **Reset defaults**
|
||||
- **General**
|
||||
- **Color scheme type:**
|
||||
- **Dark**
|
||||
- **Light**
|
||||
- **Frame shading**
|
||||
- several more categories...
|
||||
|
||||
|
||||
|
||||
# Keyboard
|
||||
|
||||
- **Import**
|
||||
- **Export**
|
||||
- **Reset defaults**
|
||||
- several categories of keybinds...
|
||||
- click on a keybind then enter a key or key combination to change it
|
||||
- right-click to clear the keybind
|
|
@ -127,14 +127,20 @@ bool TAAudioSDL::init(TAAudioDesc& request, TAAudioDesc& response) {
|
|||
ac.callback=taSDLProcess;
|
||||
ac.userdata=this;
|
||||
|
||||
ai=SDL_OpenAudioDevice(request.deviceName.empty()?NULL:request.deviceName.c_str(),0,&ac,&ar,SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
|
||||
ai=SDL_OpenAudioDevice(request.deviceName.empty()?NULL:request.deviceName.c_str(),0,&ac,&ar,0);
|
||||
if (ai==0) {
|
||||
logE("could not open audio device: %s",SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* backendName=SDL_GetCurrentAudioDriver();
|
||||
|
||||
desc.deviceName=request.deviceName;
|
||||
desc.name="";
|
||||
if (backendName==NULL) {
|
||||
desc.name="";
|
||||
} else {
|
||||
desc.name=backendName;
|
||||
}
|
||||
desc.rate=ar.freq;
|
||||
desc.inChans=0;
|
||||
desc.outChans=ar.channels;
|
||||
|
|
|
@ -4586,6 +4586,15 @@ bool DivEngine::initAudioBackend() {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_SDL2
|
||||
if (audioEngine==DIV_AUDIO_SDL) {
|
||||
String audioDriver=getConfString("sdlAudioDriver","");
|
||||
if (!audioDriver.empty()) {
|
||||
SDL_SetHint("SDL_HINT_AUDIODRIVER",audioDriver.c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
lowQuality=getConfInt("audioQuality",0);
|
||||
forceMono=getConfInt("forceMono",0);
|
||||
clampSamples=getConfInt("clampSamples",0);
|
||||
|
@ -4594,7 +4603,7 @@ bool DivEngine::initAudioBackend() {
|
|||
midiOutClock=getConfInt("midiOutClock",0);
|
||||
midiOutTime=getConfInt("midiOutTime",0);
|
||||
midiOutTimeRate=getConfInt("midiOutTimeRate",0);
|
||||
midiOutProgramChange = getConfInt("midiOutProgramChange",0);
|
||||
midiOutProgramChange=getConfInt("midiOutProgramChange",0);
|
||||
midiOutMode=getConfInt("midiOutMode",DIV_MIDI_MODE_NOTE);
|
||||
if (metroVol<0.0f) metroVol=0.0f;
|
||||
if (metroVol>2.0f) metroVol=2.0f;
|
||||
|
|
|
@ -570,6 +570,7 @@ class DivEngine {
|
|||
float oscSize;
|
||||
int oscReadPos, oscWritePos;
|
||||
int tickMult;
|
||||
int lastNBIns, lastNBOuts, lastNBSize;
|
||||
std::atomic<size_t> processTime;
|
||||
|
||||
void runExportThread();
|
||||
|
@ -1252,6 +1253,9 @@ class DivEngine {
|
|||
oscReadPos(0),
|
||||
oscWritePos(0),
|
||||
tickMult(1),
|
||||
lastNBIns(0),
|
||||
lastNBOuts(0),
|
||||
lastNBSize(0),
|
||||
processTime(0),
|
||||
yrw801ROM(NULL),
|
||||
tg100ROM(NULL),
|
||||
|
|
|
@ -322,7 +322,7 @@ void DivPlatformGB::tick(bool sysTick) {
|
|||
rWrite(16+i*5+4,((chan[i].keyOn||chan[i].keyOff)?0x80:0x00)|((chan[i].soundLen<64)<<6));
|
||||
} else {
|
||||
rWrite(16+i*5+3,(2048-chan[i].freq)&0xff);
|
||||
rWrite(16+i*5+4,(((2048-chan[i].freq)>>8)&7)|((chan[i].keyOn||chan[i].keyOff)?0x80:0x00)|((chan[i].soundLen<63)<<6));
|
||||
rWrite(16+i*5+4,(((2048-chan[i].freq)>>8)&7)|((chan[i].keyOn||(chan[i].keyOff && i!=2))?0x80:0x00)|((chan[i].soundLen<63)<<6));
|
||||
}
|
||||
if (enoughAlready) { // more compat garbage
|
||||
rWrite(16+i*5+1,((chan[i].duty&3)<<6)|(63-(chan[i].soundLen&63)));
|
||||
|
@ -466,7 +466,9 @@ int DivPlatformGB::dispatch(DivCommand c) {
|
|||
if (c.chan!=2) break;
|
||||
chan[c.chan].wave=c.value;
|
||||
ws.changeWave1(chan[c.chan].wave);
|
||||
chan[c.chan].keyOn=true;
|
||||
if (chan[c.chan].active) {
|
||||
chan[c.chan].keyOn=true;
|
||||
}
|
||||
break;
|
||||
case DIV_CMD_NOTE_PORTA: {
|
||||
int destFreq=NOTE_PERIODIC(c.value2);
|
||||
|
|
|
@ -1694,6 +1694,10 @@ void DivEngine::runMidiTime(int totalCycles) {
|
|||
}
|
||||
|
||||
void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size) {
|
||||
lastNBIns=inChans;
|
||||
lastNBOuts=outChans;
|
||||
lastNBSize=size;
|
||||
|
||||
if (!size) {
|
||||
logW("nextBuf called with size 0!");
|
||||
return;
|
||||
|
|
|
@ -134,6 +134,7 @@ const char* aboutLine[]={
|
|||
"fd",
|
||||
"GENATARi",
|
||||
"host12prog",
|
||||
"jvsTSX",
|
||||
"Lumigado",
|
||||
"Lunathir",
|
||||
"plane",
|
||||
|
|
|
@ -388,6 +388,34 @@ void FurnaceGUI::drawDebug() {
|
|||
ImGui::Text("System Managed Scale: %d",sysManagedScale);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Audio Debug")) {
|
||||
TAAudioDesc& audioWant=e->getAudioDescWant();
|
||||
TAAudioDesc& audioGot=e->getAudioDescGot();
|
||||
|
||||
ImGui::Text("want:");
|
||||
ImGui::Text("- name: %s",audioWant.name.c_str());
|
||||
ImGui::Text("- device name: %s",audioWant.deviceName.c_str());
|
||||
ImGui::Text("- rate: %f",audioWant.rate);
|
||||
ImGui::Text("- buffer size: %d",audioWant.bufsize);
|
||||
ImGui::Text("- fragments: %d",audioWant.fragments);
|
||||
ImGui::Text("- inputs: %d",audioWant.inChans);
|
||||
ImGui::Text("- outputs: %d",audioWant.outChans);
|
||||
ImGui::Text("- format: %d",audioWant.outFormat);
|
||||
|
||||
ImGui::Text("got:");
|
||||
ImGui::Text("- name: %s",audioGot.name.c_str());
|
||||
ImGui::Text("- device name: %s",audioGot.deviceName.c_str());
|
||||
ImGui::Text("- rate: %f",audioGot.rate);
|
||||
ImGui::Text("- buffer size: %d",audioGot.bufsize);
|
||||
ImGui::Text("- fragments: %d",audioGot.fragments);
|
||||
ImGui::Text("- inputs: %d",audioGot.inChans);
|
||||
ImGui::Text("- outputs: %d",audioGot.outChans);
|
||||
ImGui::Text("- format: %d",audioGot.outFormat);
|
||||
|
||||
ImGui::Text("last call to nextBuf(): in %d, out %d, size %d",e->lastNBIns,e->lastNBOuts,e->lastNBSize);
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Visualizer Debug")) {
|
||||
if (ImGui::BeginTable("visX",3,ImGuiTableFlags_Borders)) {
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
|
|
|
@ -6329,6 +6329,19 @@ bool FurnaceGUI::init() {
|
|||
}
|
||||
#endif
|
||||
|
||||
int numDriversA=SDL_GetNumAudioDrivers();
|
||||
if (numDriversA<0) {
|
||||
logW("could not list audio drivers! %s",SDL_GetError());
|
||||
} else {
|
||||
for (int i=0; i<numDriversA; i++) {
|
||||
const char* r=SDL_GetAudioDriver(i);
|
||||
if (r==NULL) continue;
|
||||
if (strcmp(r,"disk")==0) continue;
|
||||
if (strcmp(r,"dummy")==0) continue;
|
||||
availAudioDrivers.push_back(String(r));
|
||||
}
|
||||
}
|
||||
|
||||
int numDrivers=SDL_GetNumRenderDrivers();
|
||||
if (numDrivers<0) {
|
||||
logW("could not list render drivers! %s",SDL_GetError());
|
||||
|
|
|
@ -1305,6 +1305,7 @@ class FurnaceGUI {
|
|||
std::deque<String> recentFile;
|
||||
std::vector<DivInstrumentType> makeInsTypeList;
|
||||
std::vector<String> availRenderDrivers;
|
||||
std::vector<String> availAudioDrivers;
|
||||
|
||||
bool quit, warnQuit, willCommit, edit, modified, displayError, displayExporting, vgmExportLoop, zsmExportLoop, vgmExportPatternHints;
|
||||
bool vgmExportDirectStream, displayInsTypeList;
|
||||
|
@ -1535,6 +1536,7 @@ class FurnaceGUI {
|
|||
String macroRelLabel;
|
||||
String emptyLabel;
|
||||
String emptyLabel2;
|
||||
String sdlAudioDriver;
|
||||
DivConfig initialSys;
|
||||
|
||||
Settings():
|
||||
|
@ -1687,7 +1689,8 @@ class FurnaceGUI {
|
|||
noteRelLabel("==="),
|
||||
macroRelLabel("REL"),
|
||||
emptyLabel("..."),
|
||||
emptyLabel2("..") {}
|
||||
emptyLabel2(".."),
|
||||
sdlAudioDriver("") {}
|
||||
} settings;
|
||||
|
||||
struct Tutorial {
|
||||
|
|
|
@ -133,17 +133,20 @@ inline void FurnaceGUI::patternRow(int i, bool isPlaying, float lineHeight, int
|
|||
}
|
||||
ImGui::PopStyleColor();
|
||||
// for each column
|
||||
int mustSetXOf=0;
|
||||
for (int j=0; j<chans; j++) {
|
||||
// check if channel is not hidden
|
||||
if (!e->curSubSong->chanShow[j]) {
|
||||
patChanX[j]=ImGui::GetCursorScreenPos().x;
|
||||
continue;
|
||||
}
|
||||
int chanVolMax=e->getMaxVolumeChan(j);
|
||||
if (chanVolMax<1) chanVolMax=1;
|
||||
const DivPattern* pat=patCache[j];
|
||||
ImGui::TableNextColumn();
|
||||
patChanX[j]=ImGui::GetCursorScreenPos().x;
|
||||
for (int k=mustSetXOf; k<=j; k++) {
|
||||
patChanX[k]=ImGui::GetCursorScreenPos().x;
|
||||
}
|
||||
mustSetXOf=j+1;
|
||||
|
||||
// selection highlight flags
|
||||
int sel1XSum=sel1.xCoarse*32+sel1.xFine;
|
||||
|
@ -358,7 +361,9 @@ inline void FurnaceGUI::patternRow(int i, bool isPlaying, float lineHeight, int
|
|||
ImGui::PopStyleColor();
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
patChanX[chans]=ImGui::GetCursorScreenPos().x;
|
||||
for (int k=mustSetXOf; k<=chans; k++) {
|
||||
patChanX[k]=ImGui::GetCursorScreenPos().x;
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::drawPattern() {
|
||||
|
@ -371,7 +376,6 @@ void FurnaceGUI::drawPattern() {
|
|||
if (!patternOpen) return;
|
||||
|
||||
bool inhibitMenu=false;
|
||||
float scrollX=0;
|
||||
|
||||
if (e->isPlaying() && followPattern && (!e->isStepping() || pendingStepUpdate)) {
|
||||
cursor.y=oldRow+((pendingStepUpdate)?1:0);
|
||||
|
@ -946,7 +950,6 @@ void FurnaceGUI::drawPattern() {
|
|||
}
|
||||
demandScrollX=false;
|
||||
}
|
||||
scrollX=ImGui::GetScrollX();
|
||||
|
||||
// overflow changes order
|
||||
// TODO: this is very unreliable and sometimes it can warp you out of the song
|
||||
|
@ -1119,6 +1122,8 @@ void FurnaceGUI::drawPattern() {
|
|||
break;
|
||||
}
|
||||
|
||||
if (!e->curSubSong->chanShow[i.chan]) continue;
|
||||
|
||||
for (int j=0; j<num; j++) {
|
||||
ImVec2 partPos=ImVec2(
|
||||
off.x+patChanX[i.chan]+fmod(rand(),width),
|
||||
|
@ -1175,8 +1180,8 @@ void FurnaceGUI::drawPattern() {
|
|||
}
|
||||
|
||||
if (width>0.1) for (float j=-patChanSlideY[i]; j<ImGui::GetWindowHeight(); j+=width*0.7) {
|
||||
ImVec2 tMin=ImVec2(off.x+patChanX[i]-scrollX,off.y+j);
|
||||
ImVec2 tMax=ImVec2(off.x+patChanX[i+1]-scrollX,off.y+j+width*0.6);
|
||||
ImVec2 tMin=ImVec2(off.x+patChanX[i],off.y+j);
|
||||
ImVec2 tMax=ImVec2(off.x+patChanX[i+1],off.y+j+width*0.6);
|
||||
if (ch->portaNote<=ch->note) {
|
||||
arrowPoints[0]=ImLerp(tMin,tMax,ImVec2(0.1,1.0-0.8));
|
||||
arrowPoints[1]=ImLerp(tMin,tMax,ImVec2(0.5,1.0-0.0));
|
||||
|
|
|
@ -807,6 +807,25 @@ void FurnaceGUI::drawSettings() {
|
|||
}
|
||||
#endif
|
||||
|
||||
if (settings.audioEngine==DIV_AUDIO_SDL) {
|
||||
ImGui::Text("Driver");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::BeginCombo("##SDLADriver",settings.sdlAudioDriver.empty()?"Automatic":settings.sdlAudioDriver.c_str())) {
|
||||
if (ImGui::Selectable("Automatic",settings.sdlAudioDriver.empty())) {
|
||||
settings.sdlAudioDriver="";
|
||||
}
|
||||
for (String& i: availAudioDrivers) {
|
||||
if (ImGui::Selectable(i.c_str(),i==settings.sdlAudioDriver)) {
|
||||
settings.sdlAudioDriver=i;
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("you may need to restart Furnace for this setting to take effect.");
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Text("Device");
|
||||
ImGui::SameLine();
|
||||
String audioDevName=settings.audioDevice.empty()?"<System default>":settings.audioDevice;
|
||||
|
@ -1324,6 +1343,9 @@ void FurnaceGUI::drawSettings() {
|
|||
#endif
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("you may need to restart Furnace for this setting to take effect.");
|
||||
}
|
||||
if (curRenderBackend=="SDL") {
|
||||
if (ImGui::BeginCombo("Render driver",settings.renderDriver.empty()?"Automatic":settings.renderDriver.c_str())) {
|
||||
if (ImGui::Selectable("Automatic",settings.renderDriver.empty())) {
|
||||
|
@ -1336,6 +1358,9 @@ void FurnaceGUI::drawSettings() {
|
|||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("you may need to restart Furnace for this setting to take effect.");
|
||||
}
|
||||
}
|
||||
|
||||
bool dpiScaleAuto=(settings.dpiScale<0.5f);
|
||||
|
@ -2639,6 +2664,7 @@ void FurnaceGUI::syncSettings() {
|
|||
settings.midiOutDevice=e->getConfString("midiOutDevice","");
|
||||
settings.c163Name=e->getConfString("c163Name",DIV_C163_DEFAULT_NAME);
|
||||
settings.renderDriver=e->getConfString("renderDriver","");
|
||||
settings.sdlAudioDriver=e->getConfString("sdlAudioDriver","");
|
||||
settings.audioQuality=e->getConfInt("audioQuality",0);
|
||||
settings.audioBufSize=e->getConfInt("audioBufSize",1024);
|
||||
settings.audioRate=e->getConfInt("audioRate",44100);
|
||||
|
@ -2987,6 +3013,7 @@ void FurnaceGUI::commitSettings() {
|
|||
e->setConf("midiOutDevice",settings.midiOutDevice);
|
||||
e->setConf("c163Name",settings.c163Name);
|
||||
e->setConf("renderDriver",settings.renderDriver);
|
||||
e->setConf("sdlAudioDriver",settings.sdlAudioDriver);
|
||||
e->setConf("audioQuality",settings.audioQuality);
|
||||
e->setConf("audioBufSize",settings.audioBufSize);
|
||||
e->setConf("audioRate",settings.audioRate);
|
||||
|
|
Loading…
Reference in New Issue