mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-15 17:25:06 +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:
|
||||
|
||||
- 63: Furnace dev63
|
||||
- 62: Furnace dev62
|
||||
- 61: Furnace dev61
|
||||
- 60: Furnace dev60
|
||||
|
@ -476,6 +477,12 @@ size | description
|
|||
1?? | VIB macro
|
||||
1?? | WS 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
|
||||
|
|
|
@ -37,8 +37,8 @@
|
|||
warnings+=(String("\n")+x); \
|
||||
}
|
||||
|
||||
#define DIV_VERSION "dev62"
|
||||
#define DIV_ENGINE_VERSION 62
|
||||
#define DIV_VERSION "dev63"
|
||||
#define DIV_ENGINE_VERSION 63
|
||||
|
||||
enum DivStatusView {
|
||||
DIV_STATUS_NOTHING=0,
|
||||
|
|
|
@ -371,6 +371,13 @@ void DivInstrument::putInsData(SafeWriter* w) {
|
|||
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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,8 @@ enum DivInstrumentType {
|
|||
|
||||
struct DivInstrumentFM {
|
||||
unsigned char alg, fb, fms, ams, ops, opllPreset;
|
||||
bool fixedDrums;
|
||||
unsigned short kickFreq, snareHatFreq, tomTopFreq;
|
||||
struct Operator {
|
||||
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
|
||||
|
@ -98,7 +100,11 @@ struct DivInstrumentFM {
|
|||
fms(0),
|
||||
ams(0),
|
||||
ops(4),
|
||||
opllPreset(0) {
|
||||
opllPreset(0),
|
||||
fixedDrums(false),
|
||||
kickFreq(0x520),
|
||||
snareHatFreq(0x550),
|
||||
tomTopFreq(0x1c0) {
|
||||
// default instrument
|
||||
fb=4;
|
||||
op[0].tl=42;
|
||||
|
|
|
@ -377,7 +377,24 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
|||
if (c.chan>=6 && properDrums) { // drums mode
|
||||
chan[c.chan].insChanged=false;
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
|
||||
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);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
|
||||
}
|
||||
chan[c.chan].note=c.value;
|
||||
chan[c.chan].freqChanged=true;
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ const char* opllInsNames[17]={
|
|||
"Synth Bass",
|
||||
"Acoustic Bass",
|
||||
"Electric Guitar",
|
||||
"Drums (compatibility only!)"
|
||||
"Drums"
|
||||
};
|
||||
|
||||
enum FMParams {
|
||||
|
@ -857,7 +857,78 @@ void FurnaceGUI::drawInsEdit() {
|
|||
}
|
||||
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue