mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-16 01:35:07 +00:00
parent
8e5b3abab8
commit
8758277199
6 changed files with 123 additions and 6 deletions
|
@ -29,6 +29,7 @@ furthermore, an `or reserved` indicates this field is always present, but is res
|
||||||
|
|
||||||
the format versions are:
|
the format versions are:
|
||||||
|
|
||||||
|
- 63: Furnace dev63
|
||||||
- 62: Furnace dev62
|
- 62: Furnace dev62
|
||||||
- 61: Furnace dev61
|
- 61: Furnace dev61
|
||||||
- 60: Furnace dev60
|
- 60: Furnace dev60
|
||||||
|
@ -476,6 +477,12 @@ size | description
|
||||||
1?? | VIB macro
|
1?? | VIB macro
|
||||||
1?? | WS macro
|
1?? | WS macro
|
||||||
1?? | KSR macro
|
1?? | KSR macro
|
||||||
|
--- | **OPL drums mode data** (>=63)
|
||||||
|
1 | fixed frequency mode
|
||||||
|
1 | reserved
|
||||||
|
2 | kick frequency
|
||||||
|
2 | snare/hi-hat frequency
|
||||||
|
2 | tom/top frequency
|
||||||
```
|
```
|
||||||
|
|
||||||
# wavetable
|
# wavetable
|
||||||
|
|
|
@ -37,8 +37,8 @@
|
||||||
warnings+=(String("\n")+x); \
|
warnings+=(String("\n")+x); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DIV_VERSION "dev62"
|
#define DIV_VERSION "dev63"
|
||||||
#define DIV_ENGINE_VERSION 62
|
#define DIV_ENGINE_VERSION 63
|
||||||
|
|
||||||
enum DivStatusView {
|
enum DivStatusView {
|
||||||
DIV_STATUS_NOTHING=0,
|
DIV_STATUS_NOTHING=0,
|
||||||
|
|
|
@ -371,6 +371,13 @@ void DivInstrument::putInsData(SafeWriter* w) {
|
||||||
w->writeC(op.ksrMacro[j]);
|
w->writeC(op.ksrMacro[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OPL drum data
|
||||||
|
w->writeC(fm.fixedDrums);
|
||||||
|
w->writeC(0); // reserved
|
||||||
|
w->writeS(fm.kickFreq);
|
||||||
|
w->writeS(fm.snareHatFreq);
|
||||||
|
w->writeS(fm.tomTopFreq);
|
||||||
}
|
}
|
||||||
|
|
||||||
DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
|
DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
|
||||||
|
@ -694,6 +701,15 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OPL drum data
|
||||||
|
if (version>=63) {
|
||||||
|
fm.fixedDrums=reader.readC();
|
||||||
|
reader.readC(); // reserved
|
||||||
|
fm.kickFreq=reader.readS();
|
||||||
|
fm.snareHatFreq=reader.readS();
|
||||||
|
fm.tomTopFreq=reader.readS();
|
||||||
|
}
|
||||||
|
|
||||||
return DIV_DATA_SUCCESS;
|
return DIV_DATA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,8 @@ enum DivInstrumentType {
|
||||||
|
|
||||||
struct DivInstrumentFM {
|
struct DivInstrumentFM {
|
||||||
unsigned char alg, fb, fms, ams, ops, opllPreset;
|
unsigned char alg, fb, fms, ams, ops, opllPreset;
|
||||||
|
bool fixedDrums;
|
||||||
|
unsigned short kickFreq, snareHatFreq, tomTopFreq;
|
||||||
struct Operator {
|
struct Operator {
|
||||||
unsigned char am, ar, dr, mult, rr, sl, tl, dt2, rs, dt, d2r, ssgEnv;
|
unsigned char am, ar, dr, mult, rr, sl, tl, dt2, rs, dt, d2r, ssgEnv;
|
||||||
unsigned char dam, dvb, egt, ksl, sus, vib, ws, ksr; // YMU759/OPL/OPZ
|
unsigned char dam, dvb, egt, ksl, sus, vib, ws, ksr; // YMU759/OPL/OPZ
|
||||||
|
@ -98,7 +100,11 @@ struct DivInstrumentFM {
|
||||||
fms(0),
|
fms(0),
|
||||||
ams(0),
|
ams(0),
|
||||||
ops(4),
|
ops(4),
|
||||||
opllPreset(0) {
|
opllPreset(0),
|
||||||
|
fixedDrums(false),
|
||||||
|
kickFreq(0x520),
|
||||||
|
snareHatFreq(0x550),
|
||||||
|
tomTopFreq(0x1c0) {
|
||||||
// default instrument
|
// default instrument
|
||||||
fb=4;
|
fb=4;
|
||||||
op[0].tl=42;
|
op[0].tl=42;
|
||||||
|
|
|
@ -377,7 +377,24 @@ 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;
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
|
if (chan[c.chan].state.opllPreset==16 && chan[c.chan].state.fixedDrums) {
|
||||||
|
switch (c.chan) {
|
||||||
|
case 6:
|
||||||
|
chan[c.chan].baseFreq=(chan[c.chan].state.kickFreq&511)<<(chan[c.chan].state.kickFreq>>9);
|
||||||
|
break;
|
||||||
|
case 7: case 10:
|
||||||
|
chan[c.chan].baseFreq=(chan[c.chan].state.snareHatFreq&511)<<(chan[c.chan].state.snareHatFreq>>9);
|
||||||
|
break;
|
||||||
|
case 8: case 9:
|
||||||
|
chan[c.chan].baseFreq=(chan[c.chan].state.tomTopFreq&511)<<(chan[c.chan].state.tomTopFreq>>9);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
|
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
|
||||||
|
}
|
||||||
chan[c.chan].note=c.value;
|
chan[c.chan].note=c.value;
|
||||||
chan[c.chan].freqChanged=true;
|
chan[c.chan].freqChanged=true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ const char* opllInsNames[17]={
|
||||||
"Synth Bass",
|
"Synth Bass",
|
||||||
"Acoustic Bass",
|
"Acoustic Bass",
|
||||||
"Electric Guitar",
|
"Electric Guitar",
|
||||||
"Drums (compatibility only!)"
|
"Drums"
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FMParams {
|
enum FMParams {
|
||||||
|
@ -857,7 +857,78 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ins->type==DIV_INS_OPLL && ins->fm.opllPreset==16) {
|
if (ins->type==DIV_INS_OPLL && ins->fm.opllPreset==16) {
|
||||||
ImGui::Text("the Drums patch is only there for compatibility.\nit is highly encouraged you use the OPLL (drums) system instead!");
|
P(ImGui::Checkbox("Fixed frequency mode",&ins->fm.fixedDrums));
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip("when enabled, drums will be set to the specified frequencies, ignoring the note.");
|
||||||
|
}
|
||||||
|
if (ins->fm.fixedDrums) {
|
||||||
|
int block=0;
|
||||||
|
int fNum=0;
|
||||||
|
if (ImGui::BeginTable("fixedDrumSettings",3)) {
|
||||||
|
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Drum");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Block");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("FreqNum");
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
block=(ins->fm.kickFreq>>9)&7;
|
||||||
|
fNum=ins->fm.kickFreq&511;
|
||||||
|
ImGui::Text("Kick");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (ImGui::InputInt("##DBlock0",&block,1,1)) {
|
||||||
|
if (block<0) block=0;
|
||||||
|
if (block>7) block=7;
|
||||||
|
ins->fm.kickFreq=(block<<9)|fNum;
|
||||||
|
}
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (ImGui::InputInt("##DFreq0",&fNum,1,1)) {
|
||||||
|
if (fNum<0) fNum=0;
|
||||||
|
if (fNum>511) fNum=511;
|
||||||
|
ins->fm.kickFreq=(block<<9)|fNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
block=(ins->fm.snareHatFreq>>9)&7;
|
||||||
|
fNum=ins->fm.snareHatFreq&511;
|
||||||
|
ImGui::Text("Snare/Hi-hat");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (ImGui::InputInt("##DBlock1",&block,1,1)) {
|
||||||
|
if (block<0) block=0;
|
||||||
|
if (block>7) block=7;
|
||||||
|
ins->fm.snareHatFreq=(block<<9)|fNum;
|
||||||
|
}
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (ImGui::InputInt("##DFreq1",&fNum,1,1)) {
|
||||||
|
if (fNum<0) fNum=0;
|
||||||
|
if (fNum>511) fNum=511;
|
||||||
|
ins->fm.snareHatFreq=(block<<9)|fNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
block=(ins->fm.tomTopFreq>>9)&7;
|
||||||
|
fNum=ins->fm.tomTopFreq&511;
|
||||||
|
ImGui::Text("Tom/Top");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (ImGui::InputInt("##DBlock2",&block,1,1)) {
|
||||||
|
if (block<0) block=0;
|
||||||
|
if (block>7) block=7;
|
||||||
|
ins->fm.tomTopFreq=(block<<9)|fNum;
|
||||||
|
}
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (ImGui::InputInt("##DFreq2",&fNum,1,1)) {
|
||||||
|
if (fNum<0) fNum=0;
|
||||||
|
if (fNum>511) fNum=511;
|
||||||
|
ins->fm.tomTopFreq=(block<<9)|fNum;
|
||||||
|
}
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool willDisplayOps=true;
|
bool willDisplayOps=true;
|
||||||
|
|
Loading…
Reference in a new issue