Merge branch 'tildearrow:master' into master
This commit is contained in:
commit
8a8c8406b7
|
@ -411,7 +411,7 @@ target_include_directories(furnace SYSTEM PRIVATE ${DEPENDENCIES_INCLUDE_DIRS})
|
|||
target_compile_definitions(furnace PRIVATE ${DEPENDENCIES_DEFINES} IMGUI_USER_CONFIG="imconfig_fur.h")
|
||||
target_compile_options(furnace PRIVATE ${DEPENDENCIES_COMPILE_OPTIONS})
|
||||
target_link_libraries(furnace PRIVATE ${DEPENDENCIES_LIBRARIES})
|
||||
if (PKG_CONFIG_FOUND AND (SYSTEM_FMT OR SYSTEM_LIBSNDFILE OR SYSTEM_ZLIB OR SYSTEM_SDL2 OR WITH_JACK))
|
||||
if (PKG_CONFIG_FOUND AND (SYSTEM_FMT OR SYSTEM_LIBSNDFILE OR SYSTEM_ZLIB OR SYSTEM_SDL2 OR SYSTEM_RTMIDI OR WITH_JACK))
|
||||
if ("${CMAKE_VERSION}" VERSION_LESS "3.13")
|
||||
message(WARNING
|
||||
"CMake version is <3.13, using old pkg-config LDFLAGS. "
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# additional modifications for Furnace by tildearrow.
|
||||
|
||||
# Set minimum CMake required version for this project.
|
||||
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
# Define a C++ project.
|
||||
project(RtMidi LANGUAGES CXX C)
|
||||
|
|
|
@ -150,6 +150,8 @@ size | description
|
|||
| - 0xa5: OPL3 4-op (YMF262) - 12 channels
|
||||
| - 0xa6: OPL3 4-op + drums (YMF262) - 14 channels
|
||||
| - 0xa7: OPLL drums (YM2413) - 11 channels
|
||||
| - 0xa8: Atari Lynx - 4 channels
|
||||
| - 0xe0: QSound - 16 channels
|
||||
32 | sound chip volumes
|
||||
| - signed char, 64=1.0, 127=~2.0
|
||||
32 | sound chip panning
|
||||
|
|
|
@ -743,6 +743,7 @@ void DivEngine::getCommandStream(std::vector<DivCommand>& where) {
|
|||
}
|
||||
|
||||
void DivEngine::playSub(bool preserveDrift, int goalRow) {
|
||||
for (int i=0; i<song.systemLen; i++) disCont[i].dispatch->setSkipRegisterWrites(false);
|
||||
reset();
|
||||
if (preserveDrift && curOrder==0) return;
|
||||
bool oldRepeatPattern=repeatPattern;
|
||||
|
@ -767,11 +768,11 @@ void DivEngine::playSub(bool preserveDrift, int goalRow) {
|
|||
playing=true;
|
||||
for (int i=0; i<song.systemLen; i++) disCont[i].dispatch->setSkipRegisterWrites(true);
|
||||
while (playing && curOrder<goal) {
|
||||
if (nextTick(preserveDrift)) break;
|
||||
if (nextTick(preserveDrift)) return;
|
||||
}
|
||||
int oldOrder=curOrder;
|
||||
while (playing && curRow<goalRow) {
|
||||
if (nextTick(preserveDrift)) break;
|
||||
if (nextTick(preserveDrift)) return;
|
||||
if (oldOrder!=curOrder) break;
|
||||
}
|
||||
for (int i=0; i<song.systemLen; i++) disCont[i].dispatch->setSkipRegisterWrites(false);
|
||||
|
@ -1632,7 +1633,15 @@ bool DivEngine::addWaveFromFile(const char* path) {
|
|||
reader.seek(0,SEEK_SET);
|
||||
int len=reader.readI();
|
||||
wave->max=(unsigned char)reader.readC();
|
||||
if (reader.size()==(size_t)(len+5)) {
|
||||
if (wave->max==255) { // new wavetable format
|
||||
unsigned char waveVersion=reader.readC();
|
||||
logI("reading modern .dmw...\n");
|
||||
logD("wave version %d\n",waveVersion);
|
||||
wave->max=reader.readC();
|
||||
for (int i=0; i<len; i++) {
|
||||
wave->data[i]=reader.readI();
|
||||
}
|
||||
} else if (reader.size()==(size_t)(len+5)) {
|
||||
// read as .dmw
|
||||
logI("reading .dmw...\n");
|
||||
if (len>256) len=256;
|
||||
|
@ -1820,19 +1829,24 @@ void DivEngine::deepCloneOrder(bool where) {
|
|||
warnings="";
|
||||
isBusy.lock();
|
||||
for (int i=0; i<chans; i++) {
|
||||
bool didNotFind=true;
|
||||
logD("channel %d\n",i);
|
||||
order[i]=song.orders.ord[i][curOrder];
|
||||
// find free slot
|
||||
for (int j=0; j<128; j++) {
|
||||
logD("finding free slot in %d...\n",j);
|
||||
if (song.pat[i].data[j]==NULL) {
|
||||
int origOrd=order[i];
|
||||
order[i]=j;
|
||||
DivPattern* oldPat=song.pat[i].getPattern(origOrd,false);
|
||||
DivPattern* pat=song.pat[i].getPattern(j,true);
|
||||
memcpy(pat->data,oldPat->data,256*32*sizeof(short));
|
||||
logD("found at %d\n",j);
|
||||
didNotFind=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (order[i]==song.orders.ord[i][curOrder]) {
|
||||
if (didNotFind) {
|
||||
addWarning(fmt::sprintf("no free patterns in channel %d!",i));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -619,10 +619,12 @@ int DivPlatformArcade::dispatch(DivCommand c) {
|
|||
}
|
||||
}
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].keyOn=false;
|
||||
chan[c.chan].active=false;
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].keyOn=false;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].std.release();
|
||||
break;
|
||||
|
@ -851,6 +853,10 @@ void DivPlatformArcade::forceIns() {
|
|||
rWrite(chanOffs[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3)|((chan[i].chVolL&1)<<6)|((chan[i].chVolR&1)<<7));
|
||||
}
|
||||
rWrite(chanOffs[i]+ADDR_FMS_AMS,((chan[i].state.fms&7)<<4)|(chan[i].state.ams&3));
|
||||
if (chan[i].active) {
|
||||
chan[i].keyOn=true;
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
}
|
||||
for (int i=8; i<13; i++) {
|
||||
chan[i].insChanged=true;
|
||||
|
|
|
@ -171,13 +171,13 @@ void DivPlatformC64::tick() {
|
|||
if (!chan[i].resetMask && !isMuted[i]) {
|
||||
rWrite(i*7+5,0);
|
||||
rWrite(i*7+6,0);
|
||||
rWrite(i*7+4,(isMuted[i]?0:(chan[i].wave<<4))|8|(chan[i].ring<<2)|(chan[i].sync<<1));
|
||||
rWrite(i*7+4,(isMuted[i]?8:(chan[i].wave<<4))|8|(chan[i].ring<<2)|(chan[i].sync<<1));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chan[i].std.hadWave) {
|
||||
chan[i].wave=chan[i].std.wave;
|
||||
rWrite(i*7+4,(isMuted[i]?0:(chan[i].wave<<4))|(chan[i].ring<<2)|(chan[i].sync<<1)|chan[i].active);
|
||||
rWrite(i*7+4,(isMuted[i]?8:(chan[i].wave<<4))|(chan[i].ring<<2)|(chan[i].sync<<1)|chan[i].active);
|
||||
}
|
||||
if (chan[i].std.hadEx1) {
|
||||
filtControl=chan[i].std.ex1&15;
|
||||
|
@ -199,12 +199,12 @@ void DivPlatformC64::tick() {
|
|||
if (chan[i].keyOn) {
|
||||
rWrite(i*7+5,(chan[i].attack<<4)|(chan[i].decay));
|
||||
rWrite(i*7+6,(chan[i].sustain<<4)|(chan[i].release));
|
||||
rWrite(i*7+4,(isMuted[i]?0:(chan[i].wave<<4))|(chan[i].ring<<2)|(chan[i].sync<<1)|1);
|
||||
rWrite(i*7+4,(isMuted[i]?8:(chan[i].wave<<4))|(chan[i].ring<<2)|(chan[i].sync<<1)|1);
|
||||
}
|
||||
if (chan[i].keyOff && !isMuted[i]) {
|
||||
rWrite(i*7+5,(chan[i].attack<<4)|(chan[i].decay));
|
||||
rWrite(i*7+6,(chan[i].sustain<<4)|(chan[i].release));
|
||||
rWrite(i*7+4,(isMuted[i]?0:(chan[i].wave<<4))|(chan[i].ring<<2)|(chan[i].sync<<1)|0);
|
||||
rWrite(i*7+4,(isMuted[i]?8:(chan[i].wave<<4))|(chan[i].ring<<2)|(chan[i].sync<<1)|0);
|
||||
}
|
||||
rWrite(i*7,chan[i].freq&0xff);
|
||||
rWrite(i*7+1,chan[i].freq>>8);
|
||||
|
@ -246,8 +246,8 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
|||
filtCut=ins->c64.cut;
|
||||
filtRes=ins->c64.res;
|
||||
filtControl=ins->c64.lp|(ins->c64.bp<<1)|(ins->c64.hp<<2)|(ins->c64.ch3off<<3);
|
||||
updateFilter();
|
||||
}
|
||||
updateFilter();
|
||||
}
|
||||
if (chan[c.chan].insChanged) {
|
||||
chan[c.chan].insChanged=false;
|
||||
|
@ -258,11 +258,13 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
|||
case DIV_CMD_NOTE_OFF:
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].keyOn=false;
|
||||
//chan[c.chan].std.init(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].keyOn=false;
|
||||
chan[c.chan].std.release();
|
||||
break;
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
@ -328,7 +330,7 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_WAVE:
|
||||
chan[c.chan].wave=c.value;
|
||||
rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|chan[c.chan].active);
|
||||
rWrite(c.chan*7+4,(isMuted[c.chan]?8:(chan[c.chan].wave<<4))|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|chan[c.chan].active);
|
||||
break;
|
||||
case DIV_CMD_LEGATO:
|
||||
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value+((chan[c.chan].std.willArp && !chan[c.chan].std.arpMode)?(chan[c.chan].std.arp):(0)));
|
||||
|
@ -409,11 +411,11 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
|||
break;
|
||||
case 4:
|
||||
chan[c.chan].ring=c.value;
|
||||
rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|chan[c.chan].active);
|
||||
rWrite(c.chan*7+4,(isMuted[c.chan]?8:(chan[c.chan].wave<<4))|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|chan[c.chan].active);
|
||||
break;
|
||||
case 5:
|
||||
chan[c.chan].sync=c.value;
|
||||
rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|chan[c.chan].active);
|
||||
rWrite(c.chan*7+4,(isMuted[c.chan]?8:(chan[c.chan].wave<<4))|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|chan[c.chan].active);
|
||||
break;
|
||||
case 6:
|
||||
filtControl&=7;
|
||||
|
@ -432,13 +434,17 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
|||
|
||||
void DivPlatformC64::muteChannel(int ch, bool mute) {
|
||||
isMuted[ch]=mute;
|
||||
rWrite(ch*7+4,(isMuted[ch]?0:(chan[ch].wave<<4))|(chan[ch].ring<<2)|(chan[ch].sync<<1)|chan[ch].active);
|
||||
rWrite(ch*7+4,(isMuted[ch]?8:(chan[ch].wave<<4))|(chan[ch].ring<<2)|(chan[ch].sync<<1)|chan[ch].active);
|
||||
}
|
||||
|
||||
void DivPlatformC64::forceIns() {
|
||||
for (int i=0; i<3; i++) {
|
||||
chan[i].insChanged=true;
|
||||
chan[i].testWhen=0;
|
||||
if (chan[i].active) {
|
||||
chan[i].keyOn=true;
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
}
|
||||
updateFilter();
|
||||
}
|
||||
|
@ -470,7 +476,7 @@ void DivPlatformC64::reset() {
|
|||
|
||||
rWrite(0x18,0x0f);
|
||||
|
||||
filtControl=0;
|
||||
filtControl=7;
|
||||
filtRes=0;
|
||||
filtCut=2047;
|
||||
resetTime=1;
|
||||
|
|
|
@ -578,6 +578,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
if (dumpWrites) addWrite(0xffff0002,0);
|
||||
}
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].keyOn=false;
|
||||
chan[c.chan].active=false;
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
|
@ -586,6 +587,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
if (dumpWrites) addWrite(0xffff0002,0);
|
||||
}
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].keyOn=false;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].std.release();
|
||||
break;
|
||||
|
@ -781,6 +783,10 @@ void DivPlatformGenesis::forceIns() {
|
|||
}
|
||||
rWrite(chanOffs[i]+ADDR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3));
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(isMuted[i]?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
if (chan[i].active) {
|
||||
chan[i].keyOn=true;
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
}
|
||||
if (dacMode) {
|
||||
rWrite(0x2b,0x80);
|
||||
|
|
|
@ -81,6 +81,7 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) {
|
|||
}
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
opChan[ch].keyOff=true;
|
||||
opChan[ch].keyOn=false;
|
||||
opChan[ch].active=false;
|
||||
break;
|
||||
case DIV_CMD_VOLUME: {
|
||||
|
@ -315,6 +316,10 @@ void DivPlatformGenesisExt::forceIns() {
|
|||
DivPlatformGenesis::forceIns();
|
||||
for (int i=0; i<4; i++) {
|
||||
opChan[i].insChanged=true;
|
||||
if (opChan[i].active) {
|
||||
opChan[i].keyOn=true;
|
||||
opChan[i].freqChanged=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ void DivPlatformNES::tick() {
|
|||
int ntPos=chan[i].baseFreq;
|
||||
if (ntPos<0) ntPos=0;
|
||||
if (ntPos>252) ntPos=252;
|
||||
chan[i].freq=(parent->song.properNoiseLayout)?(15-(chan[i].baseFreq&15)):(noiseTable[ntPos])-1;
|
||||
chan[i].freq=(parent->song.properNoiseLayout)?(15-(chan[i].baseFreq&15)):(noiseTable[ntPos]);
|
||||
} else {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)-1;
|
||||
if (chan[i].freq>2047) chan[i].freq=2047;
|
||||
|
@ -428,10 +428,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
|
||||
void DivPlatformNES::muteChannel(int ch, bool mute) {
|
||||
isMuted[ch]=mute;
|
||||
rWrite(0x4015,(!isMuted[0])|((!isMuted[1])<<1)|((!isMuted[2])<<2)|((!isMuted[3])<<3)|((!isMuted[4])<<4));
|
||||
if (isMuted[4]) {
|
||||
rWrite(0x4011,0);
|
||||
}
|
||||
nes->muted[ch]=mute;
|
||||
}
|
||||
|
||||
void DivPlatformNES::forceIns() {
|
||||
|
@ -465,7 +462,7 @@ void DivPlatformNES::reset() {
|
|||
nes->apu.cpu_cycles=0;
|
||||
nes->apu.cpu_opcode_cycle=0;
|
||||
|
||||
rWrite(0x4015,(!isMuted[0])|((!isMuted[1])<<1)|((!isMuted[2])<<2)|((!isMuted[3])<<3)|((!isMuted[4])<<4));
|
||||
rWrite(0x4015,0x1f);
|
||||
rWrite(0x4001,chan[0].sweep);
|
||||
rWrite(0x4005,chan[1].sweep);
|
||||
}
|
||||
|
@ -510,10 +507,11 @@ int DivPlatformNES::init(DivEngine* p, int channels, int sugRate, unsigned int f
|
|||
apuType=flags;
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
nes=new struct NESAPU;
|
||||
for (int i=0; i<5; i++) {
|
||||
isMuted[i]=false;
|
||||
nes->muted[i]=false;
|
||||
}
|
||||
nes=new struct NESAPU;
|
||||
setFlags(flags);
|
||||
|
||||
init_nla_table(500,500);
|
||||
|
|
|
@ -338,15 +338,15 @@ enum apu_mode { APU_60HZ, APU_48HZ };
|
|||
#define _apu_channel_volume_adjust(ch, index)\
|
||||
((ch))
|
||||
#define s1_out(a)\
|
||||
_apu_channel_volume_adjust(a->S1.output, APU_S1)
|
||||
(a->muted[0] ? 0 : _apu_channel_volume_adjust(a->S1.output, APU_S1))
|
||||
#define s2_out(a)\
|
||||
_apu_channel_volume_adjust(a->S2.output, APU_S2)
|
||||
(a->muted[1] ? 0 : _apu_channel_volume_adjust(a->S2.output, APU_S2))
|
||||
#define tr_out(a)\
|
||||
_apu_channel_volume_adjust(a->TR.output, APU_TR)
|
||||
(a->muted[2] ? 0 : _apu_channel_volume_adjust(a->TR.output, APU_TR))
|
||||
#define ns_out(a)\
|
||||
_apu_channel_volume_adjust(a->NS.output, APU_NS)
|
||||
(a->muted[3] ? 0 : _apu_channel_volume_adjust(a->NS.output, APU_NS))
|
||||
#define dmc_out(a)\
|
||||
_apu_channel_volume_adjust(a->DMC.output, APU_DMC)
|
||||
(a->muted[4] ? 0 : _apu_channel_volume_adjust(a->DMC.output, APU_DMC))
|
||||
#define extra_out(ch)\
|
||||
(ch * cfg->apu.channel[APU_EXTRA])
|
||||
#define pulse_output(a)\
|
||||
|
@ -523,6 +523,7 @@ EXTERNC struct NESAPU {
|
|||
_apuTriangle TR;
|
||||
_apuNoise NS;
|
||||
_apuDMC DMC;
|
||||
unsigned char muted[5];
|
||||
};
|
||||
|
||||
/* apuPeriod[mode][type][cycles] */
|
||||
|
|
|
@ -515,6 +515,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
|||
break;
|
||||
}
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].keyOn=false;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].std.init(NULL);
|
||||
break;
|
||||
|
@ -528,6 +529,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
|||
break;
|
||||
}
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].keyOn=false;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].std.release();
|
||||
break;
|
||||
|
@ -829,6 +831,10 @@ void DivPlatformYM2610::forceIns() {
|
|||
}
|
||||
rWrite(chanOffs[i]+ADDR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3));
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(isMuted[i]?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
if (chan[i].active) {
|
||||
chan[i].keyOn=true;
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
}
|
||||
for (int i=4; i<14; i++) {
|
||||
chan[i].insChanged=true;
|
||||
|
|
|
@ -71,6 +71,7 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) {
|
|||
}
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
opChan[ch].keyOff=true;
|
||||
opChan[ch].keyOn=false;
|
||||
opChan[ch].active=false;
|
||||
break;
|
||||
case DIV_CMD_VOLUME: {
|
||||
|
@ -282,6 +283,10 @@ void DivPlatformYM2610Ext::forceIns() {
|
|||
DivPlatformYM2610::forceIns();
|
||||
for (int i=0; i<4; i++) {
|
||||
opChan[i].insChanged=true;
|
||||
if (opChan[i].active) {
|
||||
opChan[i].keyOn=true;
|
||||
opChan[i].freqChanged=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -499,7 +499,7 @@ const char* DivEngine::getSystemChips(DivSystem sys) {
|
|||
case DIV_SYSTEM_SMS_OPLL:
|
||||
return "TI SN76489 + Yamaha YM2413";
|
||||
case DIV_SYSTEM_GB:
|
||||
return "Game Boy";
|
||||
return "Sharp LR35902";
|
||||
case DIV_SYSTEM_PCE:
|
||||
return "Hudson Soft HuC6280";
|
||||
case DIV_SYSTEM_NES:
|
||||
|
@ -520,7 +520,7 @@ const char* DivEngine::getSystemChips(DivSystem sys) {
|
|||
case DIV_SYSTEM_AY8910:
|
||||
return "AY-3-8910";
|
||||
case DIV_SYSTEM_AMIGA:
|
||||
return "Paula";
|
||||
return "MOS 8364 Paula";
|
||||
case DIV_SYSTEM_YM2151:
|
||||
return "Yamaha YM2151 standalone";
|
||||
case DIV_SYSTEM_YM2612:
|
||||
|
|
|
@ -1002,7 +1002,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop) {
|
|||
writeLoop=true;
|
||||
}
|
||||
}
|
||||
if (nextTick()) {
|
||||
if (nextTick() || !playing) {
|
||||
done=true;
|
||||
if (!loop) {
|
||||
for (int i=0; i<song.systemLen; i++) {
|
||||
|
@ -1016,6 +1016,11 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop) {
|
|||
w->writeC(i);
|
||||
loopSample[i]=-1;
|
||||
}
|
||||
|
||||
if (!playing) {
|
||||
writeLoop=false;
|
||||
loopPos=-1;
|
||||
}
|
||||
}
|
||||
// get register dumps
|
||||
for (int i=0; i<song.systemLen; i++) {
|
||||
|
@ -1151,8 +1156,13 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop) {
|
|||
w->writeI(gd3Off-0x14);
|
||||
w->writeI(tickCount);
|
||||
if (loop) {
|
||||
w->writeI(loopPos-0x1c);
|
||||
w->writeI(tickCount-loopTick-1);
|
||||
if (loopPos==-1) {
|
||||
w->writeI(0);
|
||||
w->writeI(0);
|
||||
} else {
|
||||
w->writeI(loopPos-0x1c);
|
||||
w->writeI(tickCount-loopTick-1);
|
||||
}
|
||||
} else {
|
||||
w->writeI(0);
|
||||
w->writeI(0);
|
||||
|
|
|
@ -3824,7 +3824,7 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Save File","DefleMask 1.0/legacy module{.dmf}",workingDir,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite);
|
||||
break;
|
||||
case GUI_FILE_INS_OPEN:
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Load Instrument","compatible files{.fui,.dmp},.*",workingDir);
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Load Instrument","compatible files{.fui,.dmp,.tfi,.vgi},.*",workingDir);
|
||||
break;
|
||||
case GUI_FILE_INS_SAVE:
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Save Instrument","Furnace instrument{.fui}",workingDir,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite);
|
||||
|
@ -5492,6 +5492,11 @@ bool FurnaceGUI::init() {
|
|||
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".otf",ImVec4(0.3f,1.0f,0.6f,1.0f),ICON_FA_FONT);
|
||||
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".ttc",ImVec4(0.3f,1.0f,0.6f,1.0f),ICON_FA_FONT);
|
||||
|
||||
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".tfi",ImVec4(1.0f,0.5f,0.5f,1.0f),ICON_FA_FILE);
|
||||
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".vgi",ImVec4(1.0f,0.5f,0.5f,1.0f),ICON_FA_FILE);
|
||||
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".fti",ImVec4(1.0f,0.5f,0.5f,1.0f),ICON_FA_FILE);
|
||||
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".bti",ImVec4(1.0f,0.5f,0.5f,1.0f),ICON_FA_FILE);
|
||||
|
||||
updateWindowTitle();
|
||||
|
||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
|
|
|
@ -63,6 +63,26 @@ const char* fmParamNames[3][16]={
|
|||
{"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "D2R", "RR", "SL", "TL", "RS", "MULT", "DT", "DT2", "SSG-EG", "AM"}
|
||||
};
|
||||
|
||||
const char* opllInsNames[18]={
|
||||
"User",
|
||||
"Violin",
|
||||
"Guitar",
|
||||
"Piano",
|
||||
"Flute",
|
||||
"Clarinet",
|
||||
"Oboe",
|
||||
"Trumpet",
|
||||
"Organ",
|
||||
"Horn",
|
||||
"Synth",
|
||||
"Harpsichord",
|
||||
"Vibraphone",
|
||||
"Synth Bass",
|
||||
"Acoustic Bass",
|
||||
"Electric Guitar",
|
||||
"Drums (compatibility only!)"
|
||||
};
|
||||
|
||||
enum FMParams {
|
||||
FM_ALG=0,
|
||||
FM_FB=1,
|
||||
|
|
Loading…
Reference in New Issue