mirror of
https://github.com/tildearrow/furnace.git
synced 2025-01-03 22:21:09 +00:00
stuff
implement two systems and system vol/pan
This commit is contained in:
parent
177fe0fbdd
commit
2fcb474544
6 changed files with 72 additions and 15 deletions
|
@ -75,6 +75,7 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
|
||||||
|
|
||||||
switch (sys) {
|
switch (sys) {
|
||||||
case DIV_SYSTEM_GENESIS:
|
case DIV_SYSTEM_GENESIS:
|
||||||
|
case DIV_SYSTEM_YM2612:
|
||||||
dispatch=new DivPlatformGenesis;
|
dispatch=new DivPlatformGenesis;
|
||||||
break;
|
break;
|
||||||
case DIV_SYSTEM_GENESIS_EXT:
|
case DIV_SYSTEM_GENESIS_EXT:
|
||||||
|
@ -101,6 +102,7 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
|
||||||
((DivPlatformC64*)dispatch)->setChipModel(false);
|
((DivPlatformC64*)dispatch)->setChipModel(false);
|
||||||
break;
|
break;
|
||||||
case DIV_SYSTEM_ARCADE:
|
case DIV_SYSTEM_ARCADE:
|
||||||
|
case DIV_SYSTEM_YM2151:
|
||||||
dispatch=new DivPlatformArcade;
|
dispatch=new DivPlatformArcade;
|
||||||
((DivPlatformArcade*)dispatch)->setYMFM(true);
|
((DivPlatformArcade*)dispatch)->setYMFM(true);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1080,11 +1080,11 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
}
|
}
|
||||||
if (tchans>DIV_MAX_CHANS) tchans=DIV_MAX_CHANS;
|
if (tchans>DIV_MAX_CHANS) tchans=DIV_MAX_CHANS;
|
||||||
|
|
||||||
// system volume, skipped for now
|
// system volume
|
||||||
for (int i=0; i<32; i++) reader.readC();
|
for (int i=0; i<32; i++) ds.systemVol[i]=reader.readC();
|
||||||
|
|
||||||
// system panning, skipped for now
|
// system panning
|
||||||
for (int i=0; i<32; i++) reader.readC();
|
for (int i=0; i<32; i++) ds.systemPan[i]=reader.readC();
|
||||||
|
|
||||||
// system props, skipped for now
|
// system props, skipped for now
|
||||||
for (int i=0; i<32; i++) reader.readI();
|
for (int i=0; i<32; i++) reader.readI();
|
||||||
|
@ -1517,13 +1517,11 @@ SafeWriter* DivEngine::saveFur() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<32; i++) {
|
for (int i=0; i<32; i++) {
|
||||||
// for now
|
w->writeC(song.systemVol[i]);
|
||||||
w->writeC(64);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<32; i++) {
|
for (int i=0; i<32; i++) {
|
||||||
// for now
|
w->writeC(song.systemPan[i]);
|
||||||
w->writeC(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<32; i++) {
|
for (int i=0; i<32; i++) {
|
||||||
|
|
|
@ -101,6 +101,7 @@ bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effe
|
||||||
switch (sysOfChan[ch]) {
|
switch (sysOfChan[ch]) {
|
||||||
case DIV_SYSTEM_GENESIS:
|
case DIV_SYSTEM_GENESIS:
|
||||||
case DIV_SYSTEM_GENESIS_EXT:
|
case DIV_SYSTEM_GENESIS_EXT:
|
||||||
|
case DIV_SYSTEM_YM2612:
|
||||||
switch (effect) {
|
switch (effect) {
|
||||||
case 0x17: // DAC enable
|
case 0x17: // DAC enable
|
||||||
dispatchCmd(DivCommand(DIV_CMD_SAMPLE_MODE,ch,(effectVal>0)));
|
dispatchCmd(DivCommand(DIV_CMD_SAMPLE_MODE,ch,(effectVal>0)));
|
||||||
|
@ -179,12 +180,14 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
|
||||||
switch (sysOfChan[ch]) {
|
switch (sysOfChan[ch]) {
|
||||||
case DIV_SYSTEM_GENESIS:
|
case DIV_SYSTEM_GENESIS:
|
||||||
case DIV_SYSTEM_GENESIS_EXT:
|
case DIV_SYSTEM_GENESIS_EXT:
|
||||||
|
case DIV_SYSTEM_YM2612:
|
||||||
case DIV_SYSTEM_ARCADE:
|
case DIV_SYSTEM_ARCADE:
|
||||||
|
case DIV_SYSTEM_YM2151:
|
||||||
case DIV_SYSTEM_YM2610:
|
case DIV_SYSTEM_YM2610:
|
||||||
case DIV_SYSTEM_YM2610_EXT:
|
case DIV_SYSTEM_YM2610_EXT:
|
||||||
switch (effect) {
|
switch (effect) {
|
||||||
case 0x10: // LFO or noise mode
|
case 0x10: // LFO or noise mode
|
||||||
if (sysOfChan[ch]==DIV_SYSTEM_ARCADE) {
|
if (sysOfChan[ch]==DIV_SYSTEM_ARCADE || sysOfChan[ch]==DIV_SYSTEM_YM2151) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_FREQ,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_FREQ,ch,effectVal));
|
||||||
} else {
|
} else {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_FM_LFO,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_FM_LFO,ch,effectVal));
|
||||||
|
@ -211,12 +214,12 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x17: // arcade LFO
|
case 0x17: // arcade LFO
|
||||||
if (sysOfChan[ch]==DIV_SYSTEM_ARCADE) {
|
if (sysOfChan[ch]==DIV_SYSTEM_ARCADE || sysOfChan[ch]==DIV_SYSTEM_YM2151) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_FM_LFO,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_FM_LFO,ch,effectVal));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x18: // EXT or LFO waveform
|
case 0x18: // EXT or LFO waveform
|
||||||
if (sysOfChan[ch]==DIV_SYSTEM_ARCADE) {
|
if (sysOfChan[ch]==DIV_SYSTEM_ARCADE || sysOfChan[ch]==DIV_SYSTEM_YM2151) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_FM_LFO_WAVE,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_FM_LFO_WAVE,ch,effectVal));
|
||||||
} else {
|
} else {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_FM_EXTCH,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_FM_EXTCH,ch,effectVal));
|
||||||
|
@ -238,7 +241,7 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
|
||||||
dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,3,effectVal&31));
|
dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,3,effectVal&31));
|
||||||
break;
|
break;
|
||||||
case 0x20: // PCM frequency or Neo Geo PSG mode
|
case 0x20: // PCM frequency or Neo Geo PSG mode
|
||||||
if (sysOfChan[ch]==DIV_SYSTEM_ARCADE) {
|
if (sysOfChan[ch]==DIV_SYSTEM_ARCADE || sysOfChan[ch]==DIV_SYSTEM_YM2151) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_SAMPLE_FREQ,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_SAMPLE_FREQ,ch,effectVal));
|
||||||
} else if (sysOfChan[ch]==DIV_SYSTEM_YM2610 || sysOfChan[ch]==DIV_SYSTEM_YM2610_EXT) {
|
} else if (sysOfChan[ch]==DIV_SYSTEM_YM2610 || sysOfChan[ch]==DIV_SYSTEM_YM2610_EXT) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal));
|
||||||
|
@ -540,7 +543,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
break;
|
break;
|
||||||
case 0xe5: // pitch
|
case 0xe5: // pitch
|
||||||
chan[i].pitch=effectVal-0x80;
|
chan[i].pitch=effectVal-0x80;
|
||||||
if (sysOfChan[i]==DIV_SYSTEM_ARCADE) { // arcade pitch oddity
|
if (sysOfChan[i]==DIV_SYSTEM_ARCADE || sysOfChan[i]==DIV_SYSTEM_YM2151) { // YM2151 pitch oddity
|
||||||
chan[i].pitch*=2;
|
chan[i].pitch*=2;
|
||||||
if (chan[i].pitch<-128) chan[i].pitch=-128;
|
if (chan[i].pitch<-128) chan[i].pitch=-128;
|
||||||
if (chan[i].pitch>127) chan[i].pitch=127;
|
if (chan[i].pitch>127) chan[i].pitch=127;
|
||||||
|
@ -967,6 +970,12 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
||||||
out[1][j]+=(float)disCont[i].bbOut[0][j]/16384.0;
|
out[1][j]+=(float)disCont[i].bbOut[0][j]/16384.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
float volL=((float)song.systemVol[i]/64.0f)*((float)MIN(127,127-(int)song.systemPan[i])/127.0f);
|
||||||
|
float volR=((float)song.systemVol[i]/64.0f)*((float)MIN(127,127+(int)song.systemPan[i])/127.0f);
|
||||||
|
for (size_t j=0; j<size; j++) {
|
||||||
|
out[0][j]*=volL;
|
||||||
|
out[1][j]*=volR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metronome) for (size_t i=0; i<size; i++) {
|
if (metronome) for (size_t i=0; i<size; i++) {
|
||||||
|
|
|
@ -84,9 +84,10 @@ struct DivSong {
|
||||||
unsigned char version;
|
unsigned char version;
|
||||||
|
|
||||||
// system
|
// system
|
||||||
// TODO: multi-chip support
|
|
||||||
DivSystem system[32];
|
DivSystem system[32];
|
||||||
unsigned char systemLen;
|
unsigned char systemLen;
|
||||||
|
signed char systemVol[32];
|
||||||
|
signed char systemPan[32];
|
||||||
|
|
||||||
// song information
|
// song information
|
||||||
String name, author;
|
String name, author;
|
||||||
|
@ -146,6 +147,8 @@ struct DivSong {
|
||||||
sampleLen(0) {
|
sampleLen(0) {
|
||||||
for (int i=0; i<32; i++) {
|
for (int i=0; i<32; i++) {
|
||||||
system[i]=DIV_SYSTEM_NULL;
|
system[i]=DIV_SYSTEM_NULL;
|
||||||
|
systemVol[i]=64;
|
||||||
|
systemPan[i]=0;
|
||||||
}
|
}
|
||||||
system[0]=DIV_SYSTEM_GENESIS;
|
system[0]=DIV_SYSTEM_GENESIS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ const int _ONE_HUNDRED=100;
|
||||||
const int _ONE_HUNDRED_TWENTY_SEVEN=127;
|
const int _ONE_HUNDRED_TWENTY_SEVEN=127;
|
||||||
const int _TWO_THOUSAND_FORTY_SEVEN=2047;
|
const int _TWO_THOUSAND_FORTY_SEVEN=2047;
|
||||||
const int _FOUR_THOUSAND_NINETY_FIVE=4095;
|
const int _FOUR_THOUSAND_NINETY_FIVE=4095;
|
||||||
|
const int _MINUS_ONE_HUNDRED_TWENTY_SEVEN=-127;
|
||||||
|
|
||||||
const FurnaceGUIColors fxColors[16]={
|
const FurnaceGUIColors fxColors[16]={
|
||||||
GUI_COLOR_PATTERN_EFFECT_MISC, // 00
|
GUI_COLOR_PATTERN_EFFECT_MISC, // 00
|
||||||
|
@ -1190,6 +1191,32 @@ void FurnaceGUI::drawSampleEdit() {
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FurnaceGUI::drawMixer() {
|
||||||
|
if (!mixerOpen) return;
|
||||||
|
if (ImGui::Begin("Mixer",&mixerOpen,ImGuiWindowFlags_NoDocking)) {
|
||||||
|
char id[32];
|
||||||
|
ImGui::Columns(3);
|
||||||
|
for (int i=0; i<e->song.systemLen; i++) {
|
||||||
|
snprintf(id,31,"MixS%d",i);
|
||||||
|
bool doInvert=e->song.systemVol[i]&128;
|
||||||
|
signed char vol=e->song.systemVol[i]&127;
|
||||||
|
ImGui::PushID(id);
|
||||||
|
if (ImGui::SliderScalar("##Volume",ImGuiDataType_S8,&vol,&_ZERO,&_ONE_HUNDRED_TWENTY_SEVEN)) {
|
||||||
|
e->song.systemVol[i]=(e->song.systemVol[i]&128)|vol;
|
||||||
|
}
|
||||||
|
ImGui::NextColumn();
|
||||||
|
ImGui::SliderScalar("##Panning",ImGuiDataType_S8,&e->song.systemPan[i],&_MINUS_ONE_HUNDRED_TWENTY_SEVEN,&_ONE_HUNDRED_TWENTY_SEVEN);
|
||||||
|
ImGui::NextColumn();
|
||||||
|
if (ImGui::Checkbox("Invert",&doInvert)) {
|
||||||
|
e->song.systemVol[i]^=128;
|
||||||
|
}
|
||||||
|
ImGui::NextColumn();
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
void FurnaceGUI::drawPattern() {
|
void FurnaceGUI::drawPattern() {
|
||||||
if (!patternOpen) return;
|
if (!patternOpen) return;
|
||||||
if (e->isPlaying() && followPattern) cursor.y=oldRow;
|
if (e->isPlaying() && followPattern) cursor.y=oldRow;
|
||||||
|
@ -2866,6 +2893,12 @@ bool FurnaceGUI::loop() {
|
||||||
sysAddOption(DIV_SYSTEM_ARCADE);
|
sysAddOption(DIV_SYSTEM_ARCADE);
|
||||||
sysAddOption(DIV_SYSTEM_YM2610);
|
sysAddOption(DIV_SYSTEM_YM2610);
|
||||||
sysAddOption(DIV_SYSTEM_YM2610_EXT);
|
sysAddOption(DIV_SYSTEM_YM2610_EXT);
|
||||||
|
sysAddOption(DIV_SYSTEM_AY8910);
|
||||||
|
sysAddOption(DIV_SYSTEM_AMIGA);
|
||||||
|
sysAddOption(DIV_SYSTEM_YM2151);
|
||||||
|
sysAddOption(DIV_SYSTEM_YM2612);
|
||||||
|
sysAddOption(DIV_SYSTEM_TIA);
|
||||||
|
sysAddOption(DIV_SYSTEM_SAA1099);
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginMenu("change platform...")) {
|
if (ImGui::BeginMenu("change platform...")) {
|
||||||
|
@ -2882,6 +2915,12 @@ bool FurnaceGUI::loop() {
|
||||||
sysChangeOption(i,DIV_SYSTEM_ARCADE);
|
sysChangeOption(i,DIV_SYSTEM_ARCADE);
|
||||||
sysChangeOption(i,DIV_SYSTEM_YM2610);
|
sysChangeOption(i,DIV_SYSTEM_YM2610);
|
||||||
sysChangeOption(i,DIV_SYSTEM_YM2610_EXT);
|
sysChangeOption(i,DIV_SYSTEM_YM2610_EXT);
|
||||||
|
sysChangeOption(i,DIV_SYSTEM_AY8910);
|
||||||
|
sysChangeOption(i,DIV_SYSTEM_AMIGA);
|
||||||
|
sysChangeOption(i,DIV_SYSTEM_YM2151);
|
||||||
|
sysChangeOption(i,DIV_SYSTEM_YM2612);
|
||||||
|
sysChangeOption(i,DIV_SYSTEM_TIA);
|
||||||
|
sysChangeOption(i,DIV_SYSTEM_SAA1099);
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2940,6 +2979,7 @@ bool FurnaceGUI::loop() {
|
||||||
if (ImGui::MenuItem("sample editor")) sampleEditOpen=!sampleEditOpen;
|
if (ImGui::MenuItem("sample editor")) sampleEditOpen=!sampleEditOpen;
|
||||||
if (ImGui::MenuItem("orders")) ordersOpen=!ordersOpen;
|
if (ImGui::MenuItem("orders")) ordersOpen=!ordersOpen;
|
||||||
if (ImGui::MenuItem("pattern")) patternOpen=!patternOpen;
|
if (ImGui::MenuItem("pattern")) patternOpen=!patternOpen;
|
||||||
|
if (ImGui::MenuItem("mixer")) mixerOpen=!mixerOpen;
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginMenu("help")) {
|
if (ImGui::BeginMenu("help")) {
|
||||||
|
@ -2974,6 +3014,7 @@ bool FurnaceGUI::loop() {
|
||||||
drawWaveEdit();
|
drawWaveEdit();
|
||||||
drawSampleList();
|
drawSampleList();
|
||||||
drawSampleEdit();
|
drawSampleEdit();
|
||||||
|
drawMixer();
|
||||||
drawPattern();
|
drawPattern();
|
||||||
drawSettings();
|
drawSettings();
|
||||||
|
|
||||||
|
@ -3289,6 +3330,7 @@ FurnaceGUI::FurnaceGUI():
|
||||||
sampleEditOpen(false),
|
sampleEditOpen(false),
|
||||||
aboutOpen(false),
|
aboutOpen(false),
|
||||||
settingsOpen(false),
|
settingsOpen(false),
|
||||||
|
mixerOpen(false),
|
||||||
selecting(false),
|
selecting(false),
|
||||||
curNibble(false),
|
curNibble(false),
|
||||||
extraChannelButtons(false),
|
extraChannelButtons(false),
|
||||||
|
|
|
@ -67,7 +67,8 @@ enum FurnaceGUIWindows {
|
||||||
GUI_WINDOW_WAVE_LIST,
|
GUI_WINDOW_WAVE_LIST,
|
||||||
GUI_WINDOW_WAVE_EDIT,
|
GUI_WINDOW_WAVE_EDIT,
|
||||||
GUI_WINDOW_SAMPLE_LIST,
|
GUI_WINDOW_SAMPLE_LIST,
|
||||||
GUI_WINDOW_SAMPLE_EDIT
|
GUI_WINDOW_SAMPLE_EDIT,
|
||||||
|
GUI_WINDOW_MIXER
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FurnaceGUIFileDialogs {
|
enum FurnaceGUIFileDialogs {
|
||||||
|
@ -168,6 +169,7 @@ class FurnaceGUI {
|
||||||
int curIns, curWave, curSample, curOctave, oldRow, oldOrder, oldOrder1, editStep;
|
int curIns, curWave, curSample, curOctave, oldRow, oldOrder, oldOrder1, editStep;
|
||||||
bool editControlsOpen, ordersOpen, insListOpen, songInfoOpen, patternOpen, insEditOpen;
|
bool editControlsOpen, ordersOpen, insListOpen, songInfoOpen, patternOpen, insEditOpen;
|
||||||
bool waveListOpen, waveEditOpen, sampleListOpen, sampleEditOpen, aboutOpen, settingsOpen;
|
bool waveListOpen, waveEditOpen, sampleListOpen, sampleEditOpen, aboutOpen, settingsOpen;
|
||||||
|
bool mixerOpen;
|
||||||
SelectionPoint selStart, selEnd, cursor;
|
SelectionPoint selStart, selEnd, cursor;
|
||||||
bool selecting, curNibble, extraChannelButtons, followOrders, followPattern, changeAllOrders;
|
bool selecting, curNibble, extraChannelButtons, followOrders, followPattern, changeAllOrders;
|
||||||
FurnaceGUIWindows curWindow;
|
FurnaceGUIWindows curWindow;
|
||||||
|
@ -224,6 +226,7 @@ class FurnaceGUI {
|
||||||
void drawWaveEdit();
|
void drawWaveEdit();
|
||||||
void drawSampleList();
|
void drawSampleList();
|
||||||
void drawSampleEdit();
|
void drawSampleEdit();
|
||||||
|
void drawMixer();
|
||||||
void drawAbout();
|
void drawAbout();
|
||||||
void drawSettings();
|
void drawSettings();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue