Merge branch 'master' into gui-pretty
This commit is contained in:
commit
457fb785b0
BIN
demos/gameboy/freedom.fur
Normal file
BIN
demos/gameboy/freedom.fur
Normal file
Binary file not shown.
BIN
demos/gameboy/minos.fur
Normal file
BIN
demos/gameboy/minos.fur
Normal file
Binary file not shown.
BIN
demos/gameboy/spreadtro.fur
Normal file
BIN
demos/gameboy/spreadtro.fur
Normal file
Binary file not shown.
BIN
demos/multichip/track8_n163_k053260.fur
Normal file
BIN
demos/multichip/track8_n163_k053260.fur
Normal file
Binary file not shown.
|
@ -11,21 +11,19 @@ settings are saved when clicking the **OK** button at the bottom of the dialog.
|
||||||
- **Render backend**
|
- **Render backend**
|
||||||
- changing this may help with performace issues.
|
- changing this may help with performace issues.
|
||||||
- **Late render clear**
|
- **Late render clear**
|
||||||
- **Power-saving mode**
|
- **Power-saving mode**: saves power by lowering the frame rate to 2fps when idle.
|
||||||
- saves power by lowering the frame rate to 2fps when idle.
|
|
||||||
- may cause issues under Mesa drivers!
|
- may cause issues under Mesa drivers!
|
||||||
- **Disable threaded input (restart after changing!)**
|
- **Disable threaded input (restart after changing!)**: processes key presses for note preview on a separate thread (on supported platforms), which reduces latency.
|
||||||
- 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.
|
- however, crashes have been reported when threaded input is on. enable this option if that is the case.
|
||||||
- **Enable event delay**
|
- **Enable event delay**
|
||||||
- may cause issues with high-polling-rate mice when previewing notes.
|
- may cause issues with high-polling-rate mice when previewing notes.
|
||||||
|
|
||||||
### File
|
### File
|
||||||
|
|
||||||
- **Use system file picker**: use native OS file dialog instead of Furnace's.
|
- **Use system file picker**: uses native OS file dialog instead of Furnace's.
|
||||||
- **Number of recent files**
|
- **Number of recent files**: number of files to show in the _open recent..._ menu.
|
||||||
- **Compress when saving**
|
- **Compress when saving**
|
||||||
- use zlib to compress saved songs.
|
- uses zlib to compress saved songs.
|
||||||
- **Save unused patterns**
|
- **Save unused patterns**
|
||||||
- **Use new pattern format when saving**
|
- **Use new pattern format when saving**
|
||||||
- **Don't apply compatibility flags when loading .dmf**
|
- **Don't apply compatibility flags when loading .dmf**
|
||||||
|
@ -39,11 +37,11 @@ settings are saved when clicking the **OK** button at the bottom of the dialog.
|
||||||
|
|
||||||
- **Initial system**: the system of chips loaded on starting Furnace.
|
- **Initial system**: the system of chips loaded on starting Furnace.
|
||||||
- **Current system**: sets current chips as default.
|
- **Current system**: sets current chips as default.
|
||||||
- **Randomize**: set default to a random system.
|
- **Randomize**: sets default to a random system.
|
||||||
- this will not choose a random system at each start.
|
- this will not choose a random system at each start.
|
||||||
- **Reset to defaults**: sets default to "Sega Genesis/Mega Drive".
|
- **Reset to defaults**: sets default to "Sega Genesis/Mega Drive".
|
||||||
- **Name**: name for the default system. may be set to any text.
|
- **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).
|
- **Configure:**: same as in the [chip manager](../8-advanced/chip-manager.md) and [mixer](../8-advanced/mixer.md).
|
||||||
- **When creating new song**:
|
- **When creating new song**:
|
||||||
- **Display system preset selector**
|
- **Display system preset selector**
|
||||||
- **Start with initial system**
|
- **Start with initial system**
|
||||||
|
@ -70,12 +68,12 @@ settings are saved when clicking the **OK** button at the bottom of the dialog.
|
||||||
|
|
||||||
### Output
|
### Output
|
||||||
|
|
||||||
- **Backend**: select SDL or JACK for audio output.
|
- **Backend**: selects SDL or JACK for audio output.
|
||||||
- only appears on Linux, or MacOS compiled with JACK support
|
- only appears on Linux, or MacOS compiled with JACK support
|
||||||
- **Driver**
|
- **Driver**
|
||||||
- **Device**: audio device for playback.
|
- **Device**: audio device for playback.
|
||||||
- **Sample rate**
|
- **Sample rate**
|
||||||
- **Outputs**: select number of audio outputs created, up to 16.
|
- **Outputs**: number of audio outputs created, up to 16.
|
||||||
- only appears when Backend is JACK.
|
- only appears when Backend is JACK.
|
||||||
- **Channels**: number of output channels to use.
|
- **Channels**: number of output channels to use.
|
||||||
- **Buffer size**: size of buffer in both samples and milliseconds.
|
- **Buffer size**: size of buffer in both samples and milliseconds.
|
||||||
|
@ -209,8 +207,7 @@ settings are saved when clicking the **OK** button at the bottom of the dialog.
|
||||||
- **Export**: writes current layout to a .ini file.
|
- **Export**: writes current layout to a .ini file.
|
||||||
- **Reset**: resets layout to default.
|
- **Reset**: resets layout to default.
|
||||||
- **Allow docking editors**
|
- **Allow docking editors**
|
||||||
- **Remember window position**
|
- **Remember window position**: remembers the window's last position on start-up.
|
||||||
- remembers the window's last position on start-up.
|
|
||||||
- **Only allow window movement when clicking on title bar**
|
- **Only allow window movement when clicking on title bar**
|
||||||
- **Play/edit controls layout:**
|
- **Play/edit controls layout:**
|
||||||
- **Classic**
|
- **Classic**
|
||||||
|
@ -236,7 +233,7 @@ settings are saved when clicking the **OK** button at the bottom of the dialog.
|
||||||
- **No**
|
- **No**
|
||||||
- **Yes**
|
- **Yes**
|
||||||
- **Yes (while holding Ctrl only)**
|
- **Yes (while holding Ctrl only)**
|
||||||
- **Toggle channel solo on:** select which interactions with a channel header will toggle solo for that channel.
|
- **Toggle channel solo on:** selects which interactions with a channel header will toggle solo for that channel.
|
||||||
- Right-click or double click
|
- Right-click or double click
|
||||||
- Right-click
|
- Right-click
|
||||||
- Double-click
|
- Double-click
|
||||||
|
@ -248,13 +245,15 @@ settings are saved when clicking the **OK** button at the bottom of the dialog.
|
||||||
- **Pull delete affects entire channel row**
|
- **Pull delete affects entire channel row**
|
||||||
- **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.
|
- **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 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`.
|
- if on: moving the cursor onto the value `A5` and typing a "B" results in `5B`.
|
||||||
- **Effect input behavior:**
|
- **Effect input behavior:**
|
||||||
- **Move down**
|
- **Move down**
|
||||||
- **Move to effect value (otherwise move down)**
|
- **Move to effect value (otherwise move down)**
|
||||||
- **Move to effect value/next effect and wrap around**
|
- **Move to effect value/next effect and wrap around**
|
||||||
- **Delete effect value when deleting effect**
|
- **Delete effect value when deleting effect**
|
||||||
- **Change current instrument when changing instrument column (absorb)**
|
- **Change current instrument when changing instrument column (absorb)**
|
||||||
|
- **Remove instrument value when inserting note off/release**
|
||||||
|
- **Remove volume value when inserting note off/release**
|
||||||
|
|
||||||
|
|
||||||
### Cursor movement
|
### Cursor movement
|
||||||
|
@ -293,16 +292,17 @@ settings are saved when clicking the **OK** button at the bottom of the dialog.
|
||||||
|
|
||||||
### Scaling
|
### Scaling
|
||||||
|
|
||||||
- **Automatic UI scaling factor**: automatically match the OS's UI scaling.
|
- **Automatic UI scaling factor**: automatically matches the OS's UI scaling.
|
||||||
- **UI scaling factor**: only if "Automatic UI scaling factor" is off.
|
- **UI scaling factor**: only appears if "Automatic UI scaling factor" is off.
|
||||||
- **Icon size**
|
- **Icon size**
|
||||||
|
|
||||||
### Text
|
### Text
|
||||||
|
|
||||||
- **Main font**: if "Custom...", a file path selector will appear beneath.
|
- **Main font**: overall interface font.\
|
||||||
- **Size**
|
**Header font**: font for section headers.\
|
||||||
- **Pattern font**: if "Custom...", a file path selector will appear beneath.
|
**Pattern font** font for the pattern view, the order list, and related.
|
||||||
- **Size**
|
- if "Custom...", a file path selector will appear.
|
||||||
|
- **Size**: font size.
|
||||||
- **Display Japanese characters**\
|
- **Display Japanese characters**\
|
||||||
**Display Chinese (Simplified) characters**\
|
**Display Chinese (Simplified) characters**\
|
||||||
**Display Chinese (Traditional) characters**\
|
**Display Chinese (Traditional) characters**\
|
||||||
|
@ -358,7 +358,7 @@ settings are saved when clicking the **OK** button at the bottom of the dialog.
|
||||||
|
|
||||||
### Channel
|
### Channel
|
||||||
|
|
||||||
- **Channel style:**
|
- **Channel style:** sets the appearance of channel headers in pattern view.
|
||||||
- **Classic**
|
- **Classic**
|
||||||
- **Line**
|
- **Line**
|
||||||
- **Round**
|
- **Round**
|
||||||
|
@ -428,11 +428,11 @@ settings are saved when clicking the **OK** button at the bottom of the dialog.
|
||||||
- **Between Decay and Sustain Rate**
|
- **Between Decay and Sustain Rate**
|
||||||
- **After Release Rate**
|
- **After Release Rate**
|
||||||
- **Use separate colors for carriers/modulators in FM editor**
|
- **Use separate colors for carriers/modulators in FM editor**
|
||||||
- **Unsigned FM detune values**
|
- **Unsigned FM detune values**: uses the internal representation of detune values, such that detune amounts of -1, -2, and -3 are shown as 5, 6, and 7.
|
||||||
|
|
||||||
### Statistics
|
### Statistics
|
||||||
|
|
||||||
- **Chip memory usage unit:**
|
- **Chip memory usage unit:** unit for displaying memory usage in the Statistics window.
|
||||||
- **Bytes**
|
- **Bytes**
|
||||||
- **Kilobytes**
|
- **Kilobytes**
|
||||||
|
|
||||||
|
@ -440,15 +440,20 @@ settings are saved when clicking the **OK** button at the bottom of the dialog.
|
||||||
|
|
||||||
- **Rounded corners**
|
- **Rounded corners**
|
||||||
- **Border**
|
- **Border**
|
||||||
- **Fill entire window**
|
- **Mono**: displays a single monaural waveform of all sound mixed together.
|
||||||
- **Waveform goes out of bounds**
|
- if turned off, waves will be drawn on top of each other for each output channel.
|
||||||
|
- all colors are configurable via _Settings > Color > Color scheme > Oscilloscope > Wave (non-mono)._
|
||||||
|
- **Anti-aliased**: smoothes the lines of the waveform.
|
||||||
|
- slight performance cost and slightly buggy.
|
||||||
|
- **Fill entire window**: removes the gap between the waveform and the edge of the window.
|
||||||
|
- **Waveform goes out of bounds**: allows the waveform to draw past the top and bottom of the oscilloscope.
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
- **Rounded window corners**
|
- **Rounded window corners**
|
||||||
- **Rounded buttons**
|
- **Rounded buttons**
|
||||||
- **Rounded menu corners**
|
- **Rounded menu corners**
|
||||||
- **Borders around widgets**
|
- **Borders around widgets**: draws thin borders on buttons, checkboxes, text widgets, and the like.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
19
extern/nfd-modified/src/nfd_win.cpp
vendored
19
extern/nfd-modified/src/nfd_win.cpp
vendored
|
@ -532,6 +532,9 @@ nfdresult_t NFD_OpenDialogMultiple( const std::vector<std::string>& filterList,
|
||||||
nfdselcallback_t selCallback )
|
nfdselcallback_t selCallback )
|
||||||
{
|
{
|
||||||
nfdresult_t nfdResult = NFD_ERROR;
|
nfdresult_t nfdResult = NFD_ERROR;
|
||||||
|
NFDWinEvents* winEvents;
|
||||||
|
bool hasEvents=true;
|
||||||
|
DWORD eventID=0;
|
||||||
|
|
||||||
|
|
||||||
HRESULT coResult = COMInit();
|
HRESULT coResult = COMInit();
|
||||||
|
@ -566,6 +569,16 @@ nfdresult_t NFD_OpenDialogMultiple( const std::vector<std::string>& filterList,
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pass the callback
|
||||||
|
winEvents=new NFDWinEvents(selCallback);
|
||||||
|
if ( !SUCCEEDED(fileOpenDialog->Advise(winEvents,&eventID)) ) {
|
||||||
|
// error... ignore
|
||||||
|
hasEvents=false;
|
||||||
|
winEvents->Release();
|
||||||
|
} else {
|
||||||
|
winEvents->Release();
|
||||||
|
}
|
||||||
|
|
||||||
// Set a flag for multiple options
|
// Set a flag for multiple options
|
||||||
DWORD dwFlags;
|
DWORD dwFlags;
|
||||||
result = fileOpenDialog->GetOptions(&dwFlags);
|
result = fileOpenDialog->GetOptions(&dwFlags);
|
||||||
|
@ -613,8 +626,12 @@ nfdresult_t NFD_OpenDialogMultiple( const std::vector<std::string>& filterList,
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if ( fileOpenDialog )
|
if (fileOpenDialog) {
|
||||||
|
if (hasEvents) {
|
||||||
|
fileOpenDialog->Unadvise(eventID);
|
||||||
|
}
|
||||||
fileOpenDialog->Release();
|
fileOpenDialog->Release();
|
||||||
|
}
|
||||||
|
|
||||||
COMUninit(coResult);
|
COMUninit(coResult);
|
||||||
|
|
||||||
|
|
1306
res/icons.sfd
Normal file
1306
res/icons.sfd
Normal file
File diff suppressed because it is too large
Load diff
BIN
res/icons.ttf
Normal file
BIN
res/icons.ttf
Normal file
Binary file not shown.
|
@ -485,6 +485,12 @@ class DivDispatch {
|
||||||
*/
|
*/
|
||||||
virtual bool keyOffAffectsPorta(int ch);
|
virtual bool keyOffAffectsPorta(int ch);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test whether volume is global.
|
||||||
|
* @return whether it is.
|
||||||
|
*/
|
||||||
|
virtual bool isVolGlobal();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the lowest note in a portamento.
|
* get the lowest note in a portamento.
|
||||||
* @param ch the channel in question.
|
* @param ch the channel in question.
|
||||||
|
|
|
@ -216,13 +216,6 @@ void DivDispatchContainer::clear() {
|
||||||
if (dispatch->getDCOffRequired()) {
|
if (dispatch->getDCOffRequired()) {
|
||||||
dcOffCompensation=true;
|
dcOffCompensation=true;
|
||||||
}
|
}
|
||||||
// run for one cycle to determine DC offset
|
|
||||||
// TODO: SAA1099 doesn't like that
|
|
||||||
/*dispatch->acquire(bbIn[0],bbIn[1],0,1);
|
|
||||||
temp[0]=bbIn[0][0];
|
|
||||||
temp[1]=bbIn[1][0];
|
|
||||||
prevSample[0]=temp[0];
|
|
||||||
prevSample[1]=temp[1];*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, double gotRate, const DivConfig& flags) {
|
void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, double gotRate, const DivConfig& flags) {
|
||||||
|
@ -479,7 +472,7 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
|
||||||
break;
|
break;
|
||||||
case DIV_SYSTEM_NAMCO:
|
case DIV_SYSTEM_NAMCO:
|
||||||
dispatch=new DivPlatformNamcoWSG;
|
dispatch=new DivPlatformNamcoWSG;
|
||||||
// Pac-Man (TODO: support Pole Position?)
|
// Pac-Man
|
||||||
((DivPlatformNamcoWSG*)dispatch)->setDeviceType(1);
|
((DivPlatformNamcoWSG*)dispatch)->setDeviceType(1);
|
||||||
break;
|
break;
|
||||||
case DIV_SYSTEM_NAMCO_15XX:
|
case DIV_SYSTEM_NAMCO_15XX:
|
||||||
|
|
|
@ -86,6 +86,10 @@ bool DivDispatch::keyOffAffectsPorta(int ch) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DivDispatch::isVolGlobal() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int DivDispatch::getPortaFloor(int ch) {
|
int DivDispatch::getPortaFloor(int ch) {
|
||||||
return 0x00;
|
return 0x00;
|
||||||
}
|
}
|
||||||
|
|
|
@ -566,6 +566,10 @@ bool DivPlatformC64::getWantPreNote() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DivPlatformC64::isVolGlobal() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
float DivPlatformC64::getPostAmp() {
|
float DivPlatformC64::getPostAmp() {
|
||||||
return (sidCore==1)?3.0f:1.0f;
|
return (sidCore==1)?3.0f:1.0f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,6 +105,7 @@ class DivPlatformC64: public DivDispatch {
|
||||||
void notifyInsChange(int ins);
|
void notifyInsChange(int ins);
|
||||||
bool getDCOffRequired();
|
bool getDCOffRequired();
|
||||||
bool getWantPreNote();
|
bool getWantPreNote();
|
||||||
|
bool isVolGlobal();
|
||||||
float getPostAmp();
|
float getPostAmp();
|
||||||
DivMacroInt* getChanMacroInt(int ch);
|
DivMacroInt* getChanMacroInt(int ch);
|
||||||
void notifyInsDeletion(void* ins);
|
void notifyInsDeletion(void* ins);
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
#define CHIP_FREQBASE 1180068
|
#define CHIP_FREQBASE 1180068
|
||||||
|
|
||||||
|
#define DRUM_VOL(_x) (drumActivated[_x]?drumVol[_x]:15)
|
||||||
|
|
||||||
const unsigned char cycleMapOPLL[18]={
|
const unsigned char cycleMapOPLL[18]={
|
||||||
8, 7, 6, 7, 8, 7, 8, 6, 0, 1, 2, 7, 8, 9, 3, 4, 5, 9
|
8, 7, 6, 7, 8, 7, 8, 6, 0, 1, 2, 7, 8, 9, 3, 4, 5, 9
|
||||||
};
|
};
|
||||||
|
@ -52,7 +54,7 @@ void DivPlatformOPLL::acquire_nuked(short** buf, size_t len) {
|
||||||
QueuedWrite& w=writes.front();
|
QueuedWrite& w=writes.front();
|
||||||
if (w.addrOrVal) {
|
if (w.addrOrVal) {
|
||||||
OPLL_Write(&fm,1,w.val);
|
OPLL_Write(&fm,1,w.val);
|
||||||
//printf("write: %x = %.2x\n",w.addr,w.val);
|
//logV("write: %x = %.2x",w.addr,w.val);
|
||||||
regPool[w.addr&0xff]=w.val;
|
regPool[w.addr&0xff]=w.val;
|
||||||
writes.pop();
|
writes.pop();
|
||||||
delay=21;
|
delay=21;
|
||||||
|
@ -104,10 +106,10 @@ void DivPlatformOPLL::tick(bool sysTick) {
|
||||||
|
|
||||||
if (i>=6 && properDrums) {
|
if (i>=6 && properDrums) {
|
||||||
drumVol[i-6]=15-chan[i].outVol;
|
drumVol[i-6]=15-chan[i].outVol;
|
||||||
rWrite(0x36,drumVol[0]);
|
rWrite(0x36,DRUM_VOL(0));
|
||||||
rWrite(0x37,drumVol[1]|(drumVol[4]<<4));
|
rWrite(0x37,DRUM_VOL(1)|(DRUM_VOL(4)<<4));
|
||||||
rWrite(0x38,drumVol[3]|(drumVol[2]<<4));
|
rWrite(0x38,DRUM_VOL(3)|(DRUM_VOL(2)<<4));
|
||||||
} else if (i<6 || !drums) {
|
} else if (i<6 || !crapDrums) {
|
||||||
if (i<9) {
|
if (i<9) {
|
||||||
rWrite(0x30+i,((15-VOL_SCALE_LOG_BROKEN(chan[i].outVol,15-chan[i].state.op[1].tl,15))&15)|(chan[i].state.opllPreset<<4));
|
rWrite(0x30+i,((15-VOL_SCALE_LOG_BROKEN(chan[i].outVol,15-chan[i].state.op[1].tl,15))&15)|(chan[i].state.opllPreset<<4));
|
||||||
}
|
}
|
||||||
|
@ -230,16 +232,16 @@ void DivPlatformOPLL::tick(bool sysTick) {
|
||||||
if (i>=6 && properDrums) {
|
if (i>=6 && properDrums) {
|
||||||
drumState&=~(0x10>>(i-6));
|
drumState&=~(0x10>>(i-6));
|
||||||
immWrite(0x0e,0x20|drumState);
|
immWrite(0x0e,0x20|drumState);
|
||||||
logV("properDrums %d",i);
|
//logV("properDrums %d",i);
|
||||||
} else if (i>=6 && drums) {
|
} else if (i>=6 && crapDrums) {
|
||||||
drumState&=~(0x10>>(chan[i].note%12));
|
drumState&=~(0x10>>(chan[i].note%12));
|
||||||
immWrite(0x0e,0x20|drumState);
|
immWrite(0x0e,0x20|drumState);
|
||||||
logV("drums %d",i);
|
//logV("drums %d",i);
|
||||||
} else {
|
} else {
|
||||||
if (i<9) {
|
if (i<9) {
|
||||||
immWrite(0x20+i,(chan[i].freqH)|(chan[i].state.alg?0x20:0));
|
immWrite(0x20+i,(chan[i].freqH)|(chan[i].state.alg?0x20:0));
|
||||||
}
|
}
|
||||||
logV("normal %d",i);
|
//logV("normal %d",i);
|
||||||
}
|
}
|
||||||
//chan[i].keyOn=false;
|
//chan[i].keyOn=false;
|
||||||
chan[i].keyOff=false;
|
chan[i].keyOff=false;
|
||||||
|
@ -265,7 +267,21 @@ void DivPlatformOPLL::tick(bool sysTick) {
|
||||||
if (i>=6 && properDrums && (i<9 || !noTopHatFreq)) {
|
if (i>=6 && properDrums && (i<9 || !noTopHatFreq)) {
|
||||||
immWrite(0x10+drumSlot[i],freqt&0xff);
|
immWrite(0x10+drumSlot[i],freqt&0xff);
|
||||||
immWrite(0x20+drumSlot[i],freqt>>8);
|
immWrite(0x20+drumSlot[i],freqt>>8);
|
||||||
} else if (i<6 || !drums) {
|
switch (i) {
|
||||||
|
case 7:
|
||||||
|
lastFreqSH=0;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
lastFreqTT=0;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
lastFreqTT=1;
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
lastFreqSH=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (i<6 || !crapDrums) {
|
||||||
if (i<9) {
|
if (i<9) {
|
||||||
immWrite(0x10+i,freqt&0xff);
|
immWrite(0x10+i,freqt&0xff);
|
||||||
}
|
}
|
||||||
|
@ -278,7 +294,7 @@ void DivPlatformOPLL::tick(bool sysTick) {
|
||||||
immWrite(0x0e,0x20|drumState);
|
immWrite(0x0e,0x20|drumState);
|
||||||
}
|
}
|
||||||
chan[i].keyOn=false;
|
chan[i].keyOn=false;
|
||||||
} else if (chan[i].keyOn && i>=6 && drums) {
|
} else if (chan[i].keyOn && i>=6 && crapDrums) {
|
||||||
//printf("%d\n",chan[i].note%12);
|
//printf("%d\n",chan[i].note%12);
|
||||||
drumState|=(0x10>>(chan[i].note%12));
|
drumState|=(0x10>>(chan[i].note%12));
|
||||||
immWrite(0x0e,0x20|drumState);
|
immWrite(0x0e,0x20|drumState);
|
||||||
|
@ -365,22 +381,24 @@ void DivPlatformOPLL::commitState(int ch, DivInstrument* ins) {
|
||||||
}
|
}
|
||||||
if (chan[ch].state.opllPreset==16) { // compatible drums mode
|
if (chan[ch].state.opllPreset==16) { // compatible drums mode
|
||||||
if (ch>=6) {
|
if (ch>=6) {
|
||||||
drums=true;
|
if (!properDrumsSys) {
|
||||||
immWrite(0x16,0x20);
|
crapDrums=true;
|
||||||
immWrite(0x26,0x05);
|
immWrite(0x16,0x20);
|
||||||
immWrite(0x16,0x20);
|
immWrite(0x26,0x05);
|
||||||
immWrite(0x26,0x05);
|
immWrite(0x16,0x20);
|
||||||
immWrite(0x17,0x50);
|
immWrite(0x26,0x05);
|
||||||
immWrite(0x27,0x05);
|
immWrite(0x17,0x50);
|
||||||
immWrite(0x17,0x50);
|
immWrite(0x27,0x05);
|
||||||
immWrite(0x27,0x05);
|
immWrite(0x17,0x50);
|
||||||
immWrite(0x18,0xC0);
|
immWrite(0x27,0x05);
|
||||||
immWrite(0x28,0x01);
|
immWrite(0x18,0xC0);
|
||||||
|
immWrite(0x28,0x01);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ch>=6) {
|
if (ch>=6) {
|
||||||
if (drums) {
|
if (crapDrums) {
|
||||||
drums=false;
|
crapDrums=false;
|
||||||
immWrite(0x0e,0);
|
immWrite(0x0e,0);
|
||||||
drumState=0;
|
drumState=0;
|
||||||
}
|
}
|
||||||
|
@ -395,10 +413,40 @@ void DivPlatformOPLL::commitState(int ch, DivInstrument* ins) {
|
||||||
void DivPlatformOPLL::switchMode(bool mode) {
|
void DivPlatformOPLL::switchMode(bool mode) {
|
||||||
if (mode==properDrums) return;
|
if (mode==properDrums) return;
|
||||||
if (mode) {
|
if (mode) {
|
||||||
|
//logV("mode switch to DRUMS");
|
||||||
|
for (int i=0; i<5; i++) {
|
||||||
|
drumActivated[i]=chan[6+i].keyOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
immWrite(0x26,0);
|
||||||
|
immWrite(0x27,0);
|
||||||
|
immWrite(0x28,0);
|
||||||
|
immWrite(0x16,0);
|
||||||
|
immWrite(0x17,0);
|
||||||
|
immWrite(0x18,0);
|
||||||
|
immWrite(0x0e,0x20);
|
||||||
|
rWrite(0x36,DRUM_VOL(0));
|
||||||
|
rWrite(0x37,DRUM_VOL(1)|(DRUM_VOL(4)<<4));
|
||||||
|
rWrite(0x38,DRUM_VOL(3)|(DRUM_VOL(2)<<4));
|
||||||
|
oldWrites[0x36]=-1;
|
||||||
|
oldWrites[0x37]=-1;
|
||||||
|
oldWrites[0x38]=-1;
|
||||||
} else {
|
} else {
|
||||||
|
//logV("mode switch to NORMAL");
|
||||||
|
immWrite(0x0e,0x20);
|
||||||
|
immWrite(0x0e,0x00);
|
||||||
|
for (int i=6; i<9; i++) {
|
||||||
|
if (chan[i].active) {
|
||||||
|
chan[i].freqChanged=true;
|
||||||
|
chan[i].keyOff=false;
|
||||||
|
chan[i].keyOn=true;
|
||||||
|
oldWrites[0x30+i]=-1;
|
||||||
|
}
|
||||||
|
chan[i].insChanged=true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
properDrums=mode;
|
||||||
|
drumState=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformOPLL::dispatch(DivCommand c) {
|
int DivPlatformOPLL::dispatch(DivCommand c) {
|
||||||
|
@ -417,18 +465,31 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
||||||
|
|
||||||
if (c.chan>=6 && properDrums) { // drums mode
|
if (c.chan>=6 && properDrums) { // drums mode
|
||||||
chan[c.chan].insChanged=false;
|
chan[c.chan].insChanged=false;
|
||||||
|
drumActivated[c.chan-6]=true;
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
if (chan[c.chan].state.opllPreset==16 && chan[c.chan].state.fixedDrums) {
|
if (chan[c.chan].state.opllPreset==16 && chan[c.chan].state.fixedDrums) {
|
||||||
switch (c.chan) {
|
if (fixedAll) {
|
||||||
case 6:
|
chan[6].fixedFreq=(chan[c.chan].state.kickFreq&511)<<(chan[c.chan].state.kickFreq>>9);
|
||||||
chan[c.chan].fixedFreq=(chan[c.chan].state.kickFreq&511)<<(chan[c.chan].state.kickFreq>>9);
|
chan[7].fixedFreq=(chan[c.chan].state.snareHatFreq&511)<<(chan[c.chan].state.snareHatFreq>>9);
|
||||||
break;
|
chan[8].fixedFreq=(chan[c.chan].state.tomTopFreq&511)<<(chan[c.chan].state.tomTopFreq>>9);
|
||||||
case 7: case 10:
|
chan[9].fixedFreq=(chan[c.chan].state.tomTopFreq&511)<<(chan[c.chan].state.tomTopFreq>>9);
|
||||||
chan[c.chan].fixedFreq=(chan[c.chan].state.snareHatFreq&511)<<(chan[c.chan].state.snareHatFreq>>9);
|
chan[10].fixedFreq=(chan[c.chan].state.snareHatFreq&511)<<(chan[c.chan].state.snareHatFreq>>9);
|
||||||
break;
|
|
||||||
case 8: case 9:
|
chan[7].freqChanged=true;
|
||||||
chan[c.chan].fixedFreq=(chan[c.chan].state.tomTopFreq&511)<<(chan[c.chan].state.tomTopFreq>>9);
|
chan[8].freqChanged=true;
|
||||||
break;
|
chan[9].freqChanged=true;
|
||||||
|
} else {
|
||||||
|
switch (c.chan) {
|
||||||
|
case 6:
|
||||||
|
chan[c.chan].fixedFreq=(chan[c.chan].state.kickFreq&511)<<(chan[c.chan].state.kickFreq>>9);
|
||||||
|
break;
|
||||||
|
case 7: case 10:
|
||||||
|
chan[c.chan].fixedFreq=(chan[c.chan].state.snareHatFreq&511)<<(chan[c.chan].state.snareHatFreq>>9);
|
||||||
|
break;
|
||||||
|
case 8: case 9:
|
||||||
|
chan[c.chan].fixedFreq=(chan[c.chan].state.tomTopFreq&511)<<(chan[c.chan].state.tomTopFreq>>9);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
|
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
|
||||||
|
@ -438,6 +499,10 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
chan[c.chan].keyOn=true;
|
chan[c.chan].keyOn=true;
|
||||||
chan[c.chan].active=true;
|
chan[c.chan].active=true;
|
||||||
|
|
||||||
|
rWrite(0x36,DRUM_VOL(0));
|
||||||
|
rWrite(0x37,DRUM_VOL(1)|(DRUM_VOL(4)<<4));
|
||||||
|
rWrite(0x38,DRUM_VOL(3)|(DRUM_VOL(2)<<4));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,7 +513,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
||||||
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
|
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
|
||||||
chan[c.chan].note=c.value;
|
chan[c.chan].note=c.value;
|
||||||
|
|
||||||
if (c.chan>=6 && drums) {
|
if (c.chan>=6 && crapDrums) {
|
||||||
switch (chan[c.chan].note%12) {
|
switch (chan[c.chan].note%12) {
|
||||||
case 0: // kick
|
case 0: // kick
|
||||||
drumVol[0]=(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15);
|
drumVol[0]=(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15);
|
||||||
|
@ -466,9 +531,9 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
||||||
drumVol[4]=(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15);
|
drumVol[4]=(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rWrite(0x36,drumVol[0]);
|
rWrite(0x36,DRUM_VOL(0));
|
||||||
rWrite(0x37,drumVol[1]|(drumVol[4]<<4));
|
rWrite(0x37,DRUM_VOL(1)|(DRUM_VOL(4)<<4));
|
||||||
rWrite(0x38,drumVol[3]|(drumVol[2]<<4));
|
rWrite(0x38,DRUM_VOL(3)|(DRUM_VOL(2)<<4));
|
||||||
}
|
}
|
||||||
chan[c.chan].freqChanged=true;
|
chan[c.chan].freqChanged=true;
|
||||||
}
|
}
|
||||||
|
@ -503,11 +568,11 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
if (c.chan>=6 && properDrums) {
|
if (c.chan>=6 && properDrums) {
|
||||||
drumVol[c.chan-6]=15-chan[c.chan].outVol;
|
drumVol[c.chan-6]=15-chan[c.chan].outVol;
|
||||||
rWrite(0x36,drumVol[0]);
|
rWrite(0x36,DRUM_VOL(0));
|
||||||
rWrite(0x37,drumVol[1]|(drumVol[4]<<4));
|
rWrite(0x37,DRUM_VOL(1)|(DRUM_VOL(4)<<4));
|
||||||
rWrite(0x38,drumVol[3]|(drumVol[2]<<4));
|
rWrite(0x38,DRUM_VOL(3)|(DRUM_VOL(2)<<4));
|
||||||
break;
|
break;
|
||||||
} else if (c.chan<6 || !drums) {
|
} else if (c.chan<6 || !crapDrums) {
|
||||||
if (c.chan<9) {
|
if (c.chan<9) {
|
||||||
rWrite(0x30+c.chan,((15-VOL_SCALE_LOG_BROKEN(chan[c.chan].outVol,15-chan[c.chan].state.op[1].tl,15))&15)|(chan[c.chan].state.opllPreset<<4));
|
rWrite(0x30+c.chan,((15-VOL_SCALE_LOG_BROKEN(chan[c.chan].outVol,15-chan[c.chan].state.op[1].tl,15))&15)|(chan[c.chan].state.opllPreset<<4));
|
||||||
}
|
}
|
||||||
|
@ -565,7 +630,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
case DIV_CMD_LEGATO: {
|
case DIV_CMD_LEGATO: {
|
||||||
if (c.chan>=9 && !properDrums) return 0;
|
if (c.chan>=9 && !properDrums) return 0;
|
||||||
if (c.chan<6 || (!drums && !properDrums)) {
|
if (c.chan<6 || (!crapDrums && !properDrums)) {
|
||||||
if (chan[c.chan].insChanged) {
|
if (chan[c.chan].insChanged) {
|
||||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_OPLL);
|
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_OPLL);
|
||||||
commitState(c.chan,ins);
|
commitState(c.chan,ins);
|
||||||
|
@ -780,12 +845,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_FM_EXTCH:
|
case DIV_CMD_FM_EXTCH:
|
||||||
if (!properDrumsSys) break;
|
if (!properDrumsSys) break;
|
||||||
if ((int)properDrums==c.value) break;
|
if ((int)properDrums==c.value) break;
|
||||||
if (c.value) {
|
switchMode(c.value);
|
||||||
properDrums=true;
|
|
||||||
} else {
|
|
||||||
properDrums=false;
|
|
||||||
}
|
|
||||||
switchMode(properDrums);
|
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_MACRO_OFF:
|
case DIV_CMD_MACRO_OFF:
|
||||||
chan[c.chan].std.mask(c.value,true);
|
chan[c.chan].std.mask(c.value,true);
|
||||||
|
@ -840,7 +900,7 @@ void DivPlatformOPLL::forceIns() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (drums) { // WHAT?! FIX THIS!
|
if (crapDrums) { // WHAT?! FIX THIS!
|
||||||
immWrite(0x16,0x20);
|
immWrite(0x16,0x20);
|
||||||
immWrite(0x26,0x05);
|
immWrite(0x26,0x05);
|
||||||
immWrite(0x16,0x20);
|
immWrite(0x16,0x20);
|
||||||
|
@ -852,11 +912,25 @@ void DivPlatformOPLL::forceIns() {
|
||||||
immWrite(0x18,0xC0);
|
immWrite(0x18,0xC0);
|
||||||
immWrite(0x28,0x01);
|
immWrite(0x28,0x01);
|
||||||
}
|
}
|
||||||
// restore drum volumes
|
// restore drum volumes and state
|
||||||
if (properDrums) {
|
if (properDrums) {
|
||||||
rWrite(0x36,drumVol[0]);
|
rWrite(0x36,DRUM_VOL(0));
|
||||||
rWrite(0x37,drumVol[1]|(drumVol[4]<<4));
|
rWrite(0x37,DRUM_VOL(1)|(DRUM_VOL(4)<<4));
|
||||||
rWrite(0x38,drumVol[3]|(drumVol[2]<<4));
|
rWrite(0x38,DRUM_VOL(3)|(DRUM_VOL(2)<<4));
|
||||||
|
|
||||||
|
if (lastFreqSH==0) {
|
||||||
|
chan[7].freqChanged=true;
|
||||||
|
} else if (lastFreqSH==1) {
|
||||||
|
chan[10].freqChanged=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastFreqTT==0) {
|
||||||
|
chan[8].freqChanged=true;
|
||||||
|
} else if (lastFreqTT==1) {
|
||||||
|
chan[9].freqChanged=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
chan[6].freqChanged=true;
|
||||||
}
|
}
|
||||||
drumState=0;
|
drumState=0;
|
||||||
}
|
}
|
||||||
|
@ -937,16 +1011,18 @@ void DivPlatformOPLL::reset() {
|
||||||
drumState=0;
|
drumState=0;
|
||||||
lastCustomMemory=-1;
|
lastCustomMemory=-1;
|
||||||
|
|
||||||
drumVol[0]=0;
|
for (int i=0; i<5; i++) {
|
||||||
drumVol[1]=0;
|
drumVol[i]=0;
|
||||||
drumVol[2]=0;
|
drumActivated[i]=true;
|
||||||
drumVol[3]=0;
|
}
|
||||||
drumVol[4]=0;
|
|
||||||
|
|
||||||
delay=0;
|
delay=0;
|
||||||
drums=false;
|
crapDrums=false;
|
||||||
properDrums=properDrumsSys;
|
properDrums=properDrumsSys;
|
||||||
|
|
||||||
|
lastFreqSH=-1;
|
||||||
|
lastFreqTT=-1;
|
||||||
|
|
||||||
if (properDrums) {
|
if (properDrums) {
|
||||||
immWrite(0x0e,0x20);
|
immWrite(0x0e,0x20);
|
||||||
}
|
}
|
||||||
|
@ -1012,6 +1088,7 @@ void DivPlatformOPLL::setFlags(const DivConfig& flags) {
|
||||||
oscBuf[i]->rate=rate/2;
|
oscBuf[i]->rate=rate/2;
|
||||||
}
|
}
|
||||||
noTopHatFreq=flags.getBool("noTopHatFreq",false);
|
noTopHatFreq=flags.getBool("noTopHatFreq",false);
|
||||||
|
fixedAll=flags.getBool("fixedAll",false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformOPLL::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) {
|
int DivPlatformOPLL::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) {
|
||||||
|
|
|
@ -59,12 +59,18 @@ class DivPlatformOPLL: public DivDispatch {
|
||||||
unsigned char lastBusy;
|
unsigned char lastBusy;
|
||||||
unsigned char drumState;
|
unsigned char drumState;
|
||||||
unsigned char drumVol[5];
|
unsigned char drumVol[5];
|
||||||
|
bool drumActivated[5];
|
||||||
|
|
||||||
|
// -1: undefined
|
||||||
|
// 0: snare/tom
|
||||||
|
// 1: hi-hat/top
|
||||||
|
signed char lastFreqSH, lastFreqTT;
|
||||||
|
|
||||||
unsigned char regPool[256];
|
unsigned char regPool[256];
|
||||||
|
|
||||||
bool useYMFM;
|
bool useYMFM;
|
||||||
bool drums;
|
bool crapDrums;
|
||||||
bool properDrums, properDrumsSys, noTopHatFreq;
|
bool properDrums, properDrumsSys, noTopHatFreq, fixedAll;
|
||||||
bool vrc7;
|
bool vrc7;
|
||||||
|
|
||||||
unsigned char patchSet;
|
unsigned char patchSet;
|
||||||
|
|
|
@ -257,6 +257,10 @@ void DivPlatformTED::forceIns() {
|
||||||
updateCtrl=true;
|
updateCtrl=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DivPlatformTED::isVolGlobal() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void* DivPlatformTED::getChanState(int ch) {
|
void* DivPlatformTED::getChanState(int ch) {
|
||||||
return &chan[ch];
|
return &chan[ch];
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ class DivPlatformTED: public DivDispatch {
|
||||||
public:
|
public:
|
||||||
void acquire(short** buf, size_t len);
|
void acquire(short** buf, size_t len);
|
||||||
int dispatch(DivCommand c);
|
int dispatch(DivCommand c);
|
||||||
|
bool isVolGlobal();
|
||||||
void* getChanState(int chan);
|
void* getChanState(int chan);
|
||||||
DivMacroInt* getChanMacroInt(int ch);
|
DivMacroInt* getChanMacroInt(int ch);
|
||||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||||
|
|
|
@ -278,6 +278,10 @@ void DivPlatformVIC20::forceIns() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DivPlatformVIC20::isVolGlobal() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void* DivPlatformVIC20::getChanState(int ch) {
|
void* DivPlatformVIC20::getChanState(int ch) {
|
||||||
return &chan[ch];
|
return &chan[ch];
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ class DivPlatformVIC20: public DivDispatch {
|
||||||
public:
|
public:
|
||||||
void acquire(short** buf, size_t len);
|
void acquire(short** buf, size_t len);
|
||||||
int dispatch(DivCommand c);
|
int dispatch(DivCommand c);
|
||||||
|
bool isVolGlobal();
|
||||||
void* getChanState(int chan);
|
void* getChanState(int chan);
|
||||||
DivMacroInt* getChanMacroInt(int ch);
|
DivMacroInt* getChanMacroInt(int ch);
|
||||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||||
|
|
|
@ -1307,7 +1307,7 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
||||||
} else {
|
} else {
|
||||||
DivMacroInt* macroInt=disCont[dispatchOfChan[note.channel]].dispatch->getChanMacroInt(dispatchChanOfChan[note.channel]);
|
DivMacroInt* macroInt=disCont[dispatchOfChan[note.channel]].dispatch->getChanMacroInt(dispatchChanOfChan[note.channel]);
|
||||||
if (macroInt!=NULL) {
|
if (macroInt!=NULL) {
|
||||||
if (macroInt->hasRelease) {
|
if (macroInt->hasRelease && !disCont[dispatchOfChan[note.channel]].dispatch->isVolGlobal()) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_NOTE_OFF_ENV,note.channel));
|
dispatchCmd(DivCommand(DIV_CMD_NOTE_OFF_ENV,note.channel));
|
||||||
} else {
|
} else {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_NOTE_OFF,note.channel));
|
dispatchCmd(DivCommand(DIV_CMD_NOTE_OFF,note.channel));
|
||||||
|
|
|
@ -609,6 +609,14 @@ void FurnaceGUI::doAction(int what) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GUI_ACTION_INS_LIST_ADD:
|
case GUI_ACTION_INS_LIST_ADD:
|
||||||
|
if (settings.insTypeMenu) {
|
||||||
|
makeInsTypeList=e->getPossibleInsTypes();
|
||||||
|
if (makeInsTypeList.size()>1) {
|
||||||
|
displayInsTypeList=true;
|
||||||
|
displayInsTypeListMakeInsSample=-1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
curIns=e->addInstrument(cursor.xCoarse);
|
curIns=e->addInstrument(cursor.xCoarse);
|
||||||
if (curIns==-1) {
|
if (curIns==-1) {
|
||||||
showError("too many instruments!");
|
showError("too many instruments!");
|
||||||
|
|
|
@ -3919,7 +3919,7 @@ bool FurnaceGUI::loop() {
|
||||||
|
|
||||||
if (!mobileUI) {
|
if (!mobileUI) {
|
||||||
ImGui::BeginMainMenuBar();
|
ImGui::BeginMainMenuBar();
|
||||||
if (ImGui::BeginMenu("file")) {
|
if (ImGui::BeginMenu(settings.capitalMenuBar?"File":"file")) {
|
||||||
if (ImGui::MenuItem("new...",BIND_FOR(GUI_ACTION_NEW))) {
|
if (ImGui::MenuItem("new...",BIND_FOR(GUI_ACTION_NEW))) {
|
||||||
if (modified) {
|
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);
|
||||||
|
@ -4245,7 +4245,7 @@ bool FurnaceGUI::loop() {
|
||||||
} else {
|
} else {
|
||||||
exitDisabledTimer=0;
|
exitDisabledTimer=0;
|
||||||
}
|
}
|
||||||
if (ImGui::BeginMenu("edit")) {
|
if (ImGui::BeginMenu(settings.capitalMenuBar?"Edit":"edit")) {
|
||||||
ImGui::Text("...");
|
ImGui::Text("...");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (ImGui::MenuItem("undo",BIND_FOR(GUI_ACTION_UNDO))) doUndo();
|
if (ImGui::MenuItem("undo",BIND_FOR(GUI_ACTION_UNDO))) doUndo();
|
||||||
|
@ -4258,7 +4258,7 @@ bool FurnaceGUI::loop() {
|
||||||
}
|
}
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginMenu("settings")) {
|
if (ImGui::BeginMenu(settings.capitalMenuBar?"Settings":"settings")) {
|
||||||
#ifndef IS_MOBILE
|
#ifndef IS_MOBILE
|
||||||
if (ImGui::MenuItem("full screen",BIND_FOR(GUI_ACTION_FULLSCREEN),fullScreen)) {
|
if (ImGui::MenuItem("full screen",BIND_FOR(GUI_ACTION_FULLSCREEN),fullScreen)) {
|
||||||
doAction(GUI_ACTION_FULLSCREEN);
|
doAction(GUI_ACTION_FULLSCREEN);
|
||||||
|
@ -4294,7 +4294,7 @@ bool FurnaceGUI::loop() {
|
||||||
}
|
}
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginMenu("window")) {
|
if (ImGui::BeginMenu(settings.capitalMenuBar?"Window":"window")) {
|
||||||
if (ImGui::MenuItem("song information",BIND_FOR(GUI_ACTION_WINDOW_SONG_INFO),songInfoOpen)) songInfoOpen=!songInfoOpen;
|
if (ImGui::MenuItem("song information",BIND_FOR(GUI_ACTION_WINDOW_SONG_INFO),songInfoOpen)) songInfoOpen=!songInfoOpen;
|
||||||
if (ImGui::MenuItem("subsongs",BIND_FOR(GUI_ACTION_WINDOW_SUBSONGS),subSongsOpen)) subSongsOpen=!subSongsOpen;
|
if (ImGui::MenuItem("subsongs",BIND_FOR(GUI_ACTION_WINDOW_SUBSONGS),subSongsOpen)) subSongsOpen=!subSongsOpen;
|
||||||
if (ImGui::MenuItem("speed",BIND_FOR(GUI_ACTION_WINDOW_SPEED),speedOpen)) speedOpen=!speedOpen;
|
if (ImGui::MenuItem("speed",BIND_FOR(GUI_ACTION_WINDOW_SPEED),speedOpen)) speedOpen=!speedOpen;
|
||||||
|
@ -4336,7 +4336,7 @@ bool FurnaceGUI::loop() {
|
||||||
|
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginMenu("help")) {
|
if (ImGui::BeginMenu(settings.capitalMenuBar?"Help":"help")) {
|
||||||
if (ImGui::MenuItem("effect list",BIND_FOR(GUI_ACTION_WINDOW_EFFECT_LIST),effectListOpen)) effectListOpen=!effectListOpen;
|
if (ImGui::MenuItem("effect list",BIND_FOR(GUI_ACTION_WINDOW_EFFECT_LIST),effectListOpen)) effectListOpen=!effectListOpen;
|
||||||
if (ImGui::MenuItem("debug menu",BIND_FOR(GUI_ACTION_WINDOW_DEBUG))) debugOpen=!debugOpen;
|
if (ImGui::MenuItem("debug menu",BIND_FOR(GUI_ACTION_WINDOW_DEBUG))) debugOpen=!debugOpen;
|
||||||
if (ImGui::MenuItem("inspector",BIND_FOR(GUI_ACTION_WINDOW_DEBUG))) inspectorOpen=!inspectorOpen;
|
if (ImGui::MenuItem("inspector",BIND_FOR(GUI_ACTION_WINDOW_DEBUG))) inspectorOpen=!inspectorOpen;
|
||||||
|
@ -5630,6 +5630,19 @@ bool FurnaceGUI::loop() {
|
||||||
wavePreviewInit=true;
|
wavePreviewInit=true;
|
||||||
updateFMPreview=true;
|
updateFMPreview=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings.blankIns) {
|
||||||
|
e->song.ins[curIns]->fm.fb=0;
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
e->song.ins[curIns]->fm.op[i]=DivInstrumentFM::Operator();
|
||||||
|
e->song.ins[curIns]->fm.op[i].ar=31;
|
||||||
|
e->song.ins[curIns]->fm.op[i].dr=31;
|
||||||
|
e->song.ins[curIns]->fm.op[i].rr=15;
|
||||||
|
e->song.ins[curIns]->fm.op[i].tl=127;
|
||||||
|
e->song.ins[curIns]->fm.op[i].dt=3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MARK_MODIFIED;
|
MARK_MODIFIED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1548,6 +1548,8 @@ class FurnaceGUI {
|
||||||
int removeInsOff;
|
int removeInsOff;
|
||||||
int removeVolOff;
|
int removeVolOff;
|
||||||
int playOnLoad;
|
int playOnLoad;
|
||||||
|
int insTypeMenu;
|
||||||
|
int capitalMenuBar;
|
||||||
unsigned int maxUndoSteps;
|
unsigned int maxUndoSteps;
|
||||||
String mainFontPath;
|
String mainFontPath;
|
||||||
String headFontPath;
|
String headFontPath;
|
||||||
|
@ -1710,6 +1712,8 @@ class FurnaceGUI {
|
||||||
removeInsOff(0),
|
removeInsOff(0),
|
||||||
removeVolOff(0),
|
removeVolOff(0),
|
||||||
playOnLoad(0),
|
playOnLoad(0),
|
||||||
|
insTypeMenu(1),
|
||||||
|
capitalMenuBar(0),
|
||||||
maxUndoSteps(100),
|
maxUndoSteps(100),
|
||||||
mainFontPath(""),
|
mainFontPath(""),
|
||||||
headFontPath(""),
|
headFontPath(""),
|
||||||
|
|
|
@ -1407,28 +1407,40 @@ void FurnaceGUI::initSystemPresets() {
|
||||||
"Sega System 32", {
|
"Sega System 32", {
|
||||||
CH(DIV_SYSTEM_YM2612, 1.0f, 0, "clockSel=4"), // discrete 8.05MHz YM3438
|
CH(DIV_SYSTEM_YM2612, 1.0f, 0, "clockSel=4"), // discrete 8.05MHz YM3438
|
||||||
CH(DIV_SYSTEM_YM2612, 1.0f, 0, "clockSel=4"), // ^^
|
CH(DIV_SYSTEM_YM2612, 1.0f, 0, "clockSel=4"), // ^^
|
||||||
CH(DIV_SYSTEM_RF5C68, 1.0f, 0, "clockSel=2") // 12.5MHz
|
CH(DIV_SYSTEM_RF5C68, 1.0f, 0,
|
||||||
|
"clockSel=2\n"
|
||||||
|
"chipType=1\n"
|
||||||
|
) // 12.5MHz
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
ENTRY(
|
ENTRY(
|
||||||
"Sega System 32 (extended channel 3 on first OPN2C)", {
|
"Sega System 32 (extended channel 3 on first OPN2C)", {
|
||||||
CH(DIV_SYSTEM_YM2612_EXT, 1.0f, 0, "clockSel=4"), // discrete 8.05MHz YM3438
|
CH(DIV_SYSTEM_YM2612_EXT, 1.0f, 0, "clockSel=4"), // discrete 8.05MHz YM3438
|
||||||
CH(DIV_SYSTEM_YM2612, 1.0f, 0, "clockSel=4"), // ^^
|
CH(DIV_SYSTEM_YM2612, 1.0f, 0, "clockSel=4"), // ^^
|
||||||
CH(DIV_SYSTEM_RF5C68, 1.0f, 0, "clockSel=2") // 12.5MHz
|
CH(DIV_SYSTEM_RF5C68, 1.0f, 0,
|
||||||
|
"clockSel=2\n"
|
||||||
|
"chipType=1\n"
|
||||||
|
) // 12.5MHz
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
ENTRY(
|
ENTRY(
|
||||||
"Sega System 32 (extended channel 3 on second OPN2C)", {
|
"Sega System 32 (extended channel 3 on second OPN2C)", {
|
||||||
CH(DIV_SYSTEM_YM2612, 1.0f, 0, "clockSel=4"), // discrete 8.05MHz YM3438
|
CH(DIV_SYSTEM_YM2612, 1.0f, 0, "clockSel=4"), // discrete 8.05MHz YM3438
|
||||||
CH(DIV_SYSTEM_YM2612_EXT, 1.0f, 0, "clockSel=4"), // ^^
|
CH(DIV_SYSTEM_YM2612_EXT, 1.0f, 0, "clockSel=4"), // ^^
|
||||||
CH(DIV_SYSTEM_RF5C68, 1.0f, 0, "clockSel=2") // 12.5MHz
|
CH(DIV_SYSTEM_RF5C68, 1.0f, 0,
|
||||||
|
"clockSel=2\n"
|
||||||
|
"chipType=1\n"
|
||||||
|
) // 12.5MHz
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
ENTRY(
|
ENTRY(
|
||||||
"Sega System 32 (extended channel 3 on both OPN2Cs)", {
|
"Sega System 32 (extended channel 3 on both OPN2Cs)", {
|
||||||
CH(DIV_SYSTEM_YM2612_EXT, 1.0f, 0, "clockSel=4"), // discrete 8.05MHz YM3438
|
CH(DIV_SYSTEM_YM2612_EXT, 1.0f, 0, "clockSel=4"), // discrete 8.05MHz YM3438
|
||||||
CH(DIV_SYSTEM_YM2612_EXT, 1.0f, 0, "clockSel=4"), // ^^
|
CH(DIV_SYSTEM_YM2612_EXT, 1.0f, 0, "clockSel=4"), // ^^
|
||||||
CH(DIV_SYSTEM_RF5C68, 1.0f, 0, "clockSel=2") // 12.5MHz
|
CH(DIV_SYSTEM_RF5C68, 1.0f, 0,
|
||||||
|
"clockSel=2\n"
|
||||||
|
"chipType=1\n"
|
||||||
|
) // 12.5MHz
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
ENTRY(
|
ENTRY(
|
||||||
|
|
|
@ -2090,6 +2090,11 @@ void FurnaceGUI::drawSettings() {
|
||||||
}
|
}
|
||||||
ImGui::Unindent();
|
ImGui::Unindent();
|
||||||
|
|
||||||
|
bool capitalMenuBarB=settings.capitalMenuBar;
|
||||||
|
if (ImGui::Checkbox("Capitalize menu bar",&capitalMenuBarB)) {
|
||||||
|
settings.capitalMenuBar=capitalMenuBarB;
|
||||||
|
}
|
||||||
|
|
||||||
// SUBSECTION ORDERS
|
// SUBSECTION ORDERS
|
||||||
CONFIG_SUBSECTION("Orders");
|
CONFIG_SUBSECTION("Orders");
|
||||||
// sorry. temporarily disabled until ImGui has a way to add separators in tables arbitrarily.
|
// sorry. temporarily disabled until ImGui has a way to add separators in tables arbitrarily.
|
||||||
|
@ -2312,6 +2317,11 @@ void FurnaceGUI::drawSettings() {
|
||||||
settings.insEditColorize=insEditColorizeB;
|
settings.insEditColorize=insEditColorizeB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool insTypeMenuB=settings.insTypeMenu;
|
||||||
|
if (ImGui::Checkbox("Display instrument type menu when adding instrument",&insTypeMenuB)) {
|
||||||
|
settings.insTypeMenu=insTypeMenuB;
|
||||||
|
}
|
||||||
|
|
||||||
// SUBSECTION MACRO EDITOR
|
// SUBSECTION MACRO EDITOR
|
||||||
CONFIG_SUBSECTION("Macro Editor");
|
CONFIG_SUBSECTION("Macro Editor");
|
||||||
ImGui::Text("Macro editor layout:");
|
ImGui::Text("Macro editor layout:");
|
||||||
|
@ -3048,6 +3058,8 @@ void FurnaceGUI::syncSettings() {
|
||||||
settings.removeInsOff=e->getConfInt("removeInsOff",0);
|
settings.removeInsOff=e->getConfInt("removeInsOff",0);
|
||||||
settings.removeVolOff=e->getConfInt("removeVolOff",0);
|
settings.removeVolOff=e->getConfInt("removeVolOff",0);
|
||||||
settings.playOnLoad=e->getConfInt("playOnLoad",0);
|
settings.playOnLoad=e->getConfInt("playOnLoad",0);
|
||||||
|
settings.insTypeMenu=e->getConfInt("insTypeMenu",1);
|
||||||
|
settings.capitalMenuBar=e->getConfInt("capitalMenuBar",0);
|
||||||
|
|
||||||
clampSetting(settings.mainFontSize,2,96);
|
clampSetting(settings.mainFontSize,2,96);
|
||||||
clampSetting(settings.headFontSize,2,96);
|
clampSetting(settings.headFontSize,2,96);
|
||||||
|
@ -3182,6 +3194,8 @@ void FurnaceGUI::syncSettings() {
|
||||||
clampSetting(settings.removeInsOff,0,1);
|
clampSetting(settings.removeInsOff,0,1);
|
||||||
clampSetting(settings.removeVolOff,0,1);
|
clampSetting(settings.removeVolOff,0,1);
|
||||||
clampSetting(settings.playOnLoad,0,2);
|
clampSetting(settings.playOnLoad,0,2);
|
||||||
|
clampSetting(settings.insTypeMenu,0,1);
|
||||||
|
clampSetting(settings.capitalMenuBar,0,1);
|
||||||
|
|
||||||
if (settings.exportLoops<0.0) settings.exportLoops=0.0;
|
if (settings.exportLoops<0.0) settings.exportLoops=0.0;
|
||||||
if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0;
|
if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0;
|
||||||
|
@ -3416,6 +3430,8 @@ void FurnaceGUI::commitSettings() {
|
||||||
e->setConf("removeInsOff",settings.removeInsOff);
|
e->setConf("removeInsOff",settings.removeInsOff);
|
||||||
e->setConf("removeVolOff",settings.removeVolOff);
|
e->setConf("removeVolOff",settings.removeVolOff);
|
||||||
e->setConf("playOnLoad",settings.playOnLoad);
|
e->setConf("playOnLoad",settings.playOnLoad);
|
||||||
|
e->setConf("insTypeMenu",settings.insTypeMenu);
|
||||||
|
e->setConf("capitalMenuBar",settings.capitalMenuBar);
|
||||||
|
|
||||||
// colors
|
// colors
|
||||||
for (int i=0; i<GUI_COLOR_MAX; i++) {
|
for (int i=0; i<GUI_COLOR_MAX; i++) {
|
||||||
|
|
|
@ -395,6 +395,7 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
|
||||||
int clockSel=flags.getInt("clockSel",0);
|
int clockSel=flags.getInt("clockSel",0);
|
||||||
int patchSet=flags.getInt("patchSet",0);
|
int patchSet=flags.getInt("patchSet",0);
|
||||||
bool noTopHatFreq=flags.getBool("noTopHatFreq",false);
|
bool noTopHatFreq=flags.getBool("noTopHatFreq",false);
|
||||||
|
bool fixedAll=flags.getBool("fixedAll",false);
|
||||||
|
|
||||||
ImGui::Text("Clock rate:");
|
ImGui::Text("Clock rate:");
|
||||||
ImGui::Indent();
|
ImGui::Indent();
|
||||||
|
@ -441,6 +442,9 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
|
||||||
if (ImGui::Checkbox("Ignore top/hi-hat frequency changes",&noTopHatFreq)) {
|
if (ImGui::Checkbox("Ignore top/hi-hat frequency changes",&noTopHatFreq)) {
|
||||||
altered=true;
|
altered=true;
|
||||||
}
|
}
|
||||||
|
if (ImGui::Checkbox("Apply fixed frequency to all drums at once",&fixedAll)) {
|
||||||
|
altered=true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (altered) {
|
if (altered) {
|
||||||
|
@ -450,6 +454,7 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
|
||||||
flags.set("patchSet",patchSet);
|
flags.set("patchSet",patchSet);
|
||||||
}
|
}
|
||||||
flags.set("noTopHatFreq",noTopHatFreq);
|
flags.set("noTopHatFreq",noTopHatFreq);
|
||||||
|
flags.set("fixedAll",fixedAll);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue