mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-04 20:05:05 +00:00
Merge branch 'master' into ZSMv1
This commit is contained in:
commit
850508e1b8
70 changed files with 342 additions and 65 deletions
|
@ -234,7 +234,7 @@ yup, it's real.
|
||||||
|
|
||||||
> where's the manual?
|
> where's the manual?
|
||||||
|
|
||||||
see [papers/](papers/README.md). it's kind of incomplete, but at least the systems (sound chips) section is there.
|
see [papers/](papers/doc/README.md). it's kind of incomplete, but at least the systems (sound chips) section is there.
|
||||||
|
|
||||||
> it doesn't open under macOS!
|
> it doesn't open under macOS!
|
||||||
|
|
||||||
|
|
BIN
demos/Checknobankh.fur
Normal file
BIN
demos/Checknobankh.fur
Normal file
Binary file not shown.
BIN
demos/Rise_against_the_ashes_to_the_new_dawn.fur
Normal file
BIN
demos/Rise_against_the_ashes_to_the_new_dawn.fur
Normal file
Binary file not shown.
BIN
demos/The Cheetahmen.fur
Normal file
BIN
demos/The Cheetahmen.fur
Normal file
Binary file not shown.
BIN
demos/massive_x_opz.fur
Normal file
BIN
demos/massive_x_opz.fur
Normal file
Binary file not shown.
5
extern/nfd-modified/src/nfd_cocoa.mm
vendored
5
extern/nfd-modified/src/nfd_cocoa.mm
vendored
|
@ -23,7 +23,12 @@ static NSArray *BuildAllowedFileTypes( const std::vector<std::string>& filterLis
|
||||||
NSMutableArray *buildFilterList = [[NSMutableArray alloc] init];
|
NSMutableArray *buildFilterList = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
std::string typebuf;
|
std::string typebuf;
|
||||||
|
int index=-1;
|
||||||
for (const std::string& i: filterList) {
|
for (const std::string& i: filterList) {
|
||||||
|
index++;
|
||||||
|
if (!(index&1)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
typebuf="";
|
typebuf="";
|
||||||
for (const char& j: i) {
|
for (const char& j: i) {
|
||||||
if (j==' ' || j==',' || j ==';') {
|
if (j==' ' || j==',' || j ==';') {
|
||||||
|
|
4
extern/rtmidi/RtMidi.cpp
vendored
4
extern/rtmidi/RtMidi.cpp
vendored
|
@ -40,6 +40,7 @@
|
||||||
#include "RtMidi.h"
|
#include "RtMidi.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#ifdef TARGET_OS_IPHONE
|
||||||
#if (TARGET_OS_IPHONE == 1)
|
#if (TARGET_OS_IPHONE == 1)
|
||||||
|
|
||||||
#define AudioGetCurrentHostTime CAHostTimeBase::GetCurrentTime
|
#define AudioGetCurrentHostTime CAHostTimeBase::GetCurrentTime
|
||||||
|
@ -66,6 +67,7 @@
|
||||||
#define EndianS32_BtoN(n) n
|
#define EndianS32_BtoN(n) n
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// Default for Windows is to add an identifier to the port names; this
|
// Default for Windows is to add an identifier to the port names; this
|
||||||
// flag can be defined (e.g. in your project file) to disable this behaviour.
|
// flag can be defined (e.g. in your project file) to disable this behaviour.
|
||||||
|
@ -814,7 +816,7 @@ MidiOutApi :: ~MidiOutApi( void )
|
||||||
// time values.
|
// time values.
|
||||||
|
|
||||||
// These are not available on iOS.
|
// These are not available on iOS.
|
||||||
#if (TARGET_OS_IPHONE == 0)
|
#ifdef TARGET_OS_IPHONE
|
||||||
#include <CoreAudio/HostTime.h>
|
#include <CoreAudio/HostTime.h>
|
||||||
#include <CoreServices/CoreServices.h>
|
#include <CoreServices/CoreServices.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
BIN
instruments/FM/bass/Acoustic Bass.dmp
Normal file
BIN
instruments/FM/bass/Acoustic Bass.dmp
Normal file
Binary file not shown.
87
instruments/FM/bass/Basses.opm
Normal file
87
instruments/FM/bass/Basses.opm
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
//LFO: LFRQ AMD PMD WF NFRQ
|
||||||
|
//@:[Num] [Name]
|
||||||
|
//CH: PAN FL CON AMS PMS SLOT NE
|
||||||
|
//OP: AR D1R D2R RR D1L TL KS MUL DT1 DT2 AMS-EN
|
||||||
|
|
||||||
|
// vgm offset = 000001d3, channels used = 1-------
|
||||||
|
@:0 Acoustic Bass
|
||||||
|
LFO: 0 0 0 0 0
|
||||||
|
CH: 64 0 0 0 0 120 0
|
||||||
|
M1: 25 18 14 6 3 28 0 5 6 0 0
|
||||||
|
C1: 28 26 8 6 7 31 0 4 2 0 0
|
||||||
|
M2: 27 7 0 6 15 21 0 1 1 0 0
|
||||||
|
C2: 29 11 10 8 2 0 0 1 3 0 0
|
||||||
|
|
||||||
|
// vgm offset = 0000024e, channels used = 12------
|
||||||
|
@:1 StringSlapSFX
|
||||||
|
LFO: 0 0 0 0 0
|
||||||
|
CH: 64 7 4 0 0 120 0
|
||||||
|
M1: 19 16 0 10 15 3 0 0 5 0 0
|
||||||
|
C1: 31 20 0 9 15 4 0 7 0 0 0
|
||||||
|
M2: 31 18 0 1 15 16 0 2 3 0 0
|
||||||
|
C2: 31 17 0 9 15 30 0 1 3 0 0
|
||||||
|
|
||||||
|
// vgm offset = 0000093e, channels used = 1-------
|
||||||
|
@:2 Finger Bass
|
||||||
|
LFO: 0 0 0 0 0
|
||||||
|
CH: 64 0 0 0 0 120 0
|
||||||
|
M1: 31 15 0 11 1 31 0 3 3 0 0
|
||||||
|
C1: 31 13 0 10 1 46 0 2 3 0 0
|
||||||
|
M2: 31 10 0 10 1 24 0 1 3 0 0
|
||||||
|
C2: 31 4 0 11 15 0 0 1 3 0 0
|
||||||
|
|
||||||
|
// vgm offset = 00000b30, channels used = 1-------
|
||||||
|
@:3 Fretless Bass
|
||||||
|
LFO: 0 0 0 0 0
|
||||||
|
CH: 64 0 0 0 0 120 0
|
||||||
|
M1: 31 0 0 3 15 21 0 1 5 0 0
|
||||||
|
C1: 31 0 0 6 15 54 0 1 0 0 0
|
||||||
|
M2: 31 0 0 7 11 26 0 1 5 0 0
|
||||||
|
C2: 31 4 0 12 15 2 0 1 0 0 0
|
||||||
|
|
||||||
|
// vgm offset = 00000d2b, channels used = 1-------
|
||||||
|
@:4 Picked Bass
|
||||||
|
LFO: 0 0 0 0 0
|
||||||
|
CH: 64 0 0 0 0 120 0
|
||||||
|
M1: 31 18 1 11 3 24 0 5 3 0 0
|
||||||
|
C1: 31 18 2 10 1 33 0 3 3 0 0
|
||||||
|
M2: 31 10 3 10 1 33 0 1 3 0 0
|
||||||
|
C2: 31 4 0 11 15 0 0 1 3 0 0
|
||||||
|
|
||||||
|
// vgm offset = 00000f2c, channels used = 1-------
|
||||||
|
@:5 Slap Bass
|
||||||
|
LFO: 0 0 0 0 0
|
||||||
|
CH: 64 0 2 0 0 120 0
|
||||||
|
M1: 31 20 0 3 15 0 1 0 0 0 0
|
||||||
|
C1: 31 23 0 4 0 43 0 15 3 0 0
|
||||||
|
M2: 31 17 0 1 2 16 1 1 3 0 0
|
||||||
|
C2: 31 9 0 10 15 2 0 1 3 0 0
|
||||||
|
|
||||||
|
// vgm offset = 00001444, channels used = 1-------
|
||||||
|
@:6 Synth Bass 1
|
||||||
|
LFO: 0 0 0 0 0
|
||||||
|
CH: 64 6 2 0 0 120 0
|
||||||
|
M1: 31 12 0 3 15 16 2 1 3 0 0
|
||||||
|
C1: 31 10 0 4 15 127 0 1 0 0 0
|
||||||
|
M2: 31 4 0 1 0 33 0 1 3 0 0
|
||||||
|
C2: 31 9 0 11 15 0 0 1 3 0 0
|
||||||
|
|
||||||
|
// vgm offset = 0000189b, channels used = 1-------
|
||||||
|
@:7 SynthBass101
|
||||||
|
LFO: 0 0 0 0 0
|
||||||
|
CH: 64 5 2 0 0 120 0
|
||||||
|
M1: 31 11 0 3 15 24 2 2 3 0 0
|
||||||
|
C1: 31 10 0 4 15 127 0 1 0 0 0
|
||||||
|
M2: 31 0 0 1 15 24 0 1 3 0 0
|
||||||
|
C2: 31 9 0 11 15 0 0 1 3 0 0
|
||||||
|
|
||||||
|
// vgm offset = 00001d22, channels used = 1-------
|
||||||
|
@:8 Synth Bass 2
|
||||||
|
LFO: 0 0 0 0 0
|
||||||
|
CH: 64 5 4 0 0 120 0
|
||||||
|
M1: 27 10 5 11 7 21 1 1 3 0 0
|
||||||
|
C1: 31 0 15 11 7 3 0 1 3 0 0
|
||||||
|
M2: 22 13 13 8 6 21 3 12 3 0 0
|
||||||
|
C2: 31 15 16 11 8 13 0 2 3 0 0
|
||||||
|
|
||||||
|
|
BIN
instruments/FM/bass/Electric Finger Bass.dmp
Normal file
BIN
instruments/FM/bass/Electric Finger Bass.dmp
Normal file
Binary file not shown.
BIN
instruments/FM/bass/Electric Fretless Bass.dmp
Normal file
BIN
instruments/FM/bass/Electric Fretless Bass.dmp
Normal file
Binary file not shown.
BIN
instruments/FM/bass/Electric Picked Bass.dmp
Normal file
BIN
instruments/FM/bass/Electric Picked Bass.dmp
Normal file
Binary file not shown.
BIN
instruments/FM/bass/Electric Slap Bass.dmp
Normal file
BIN
instruments/FM/bass/Electric Slap Bass.dmp
Normal file
Binary file not shown.
BIN
instruments/FM/bass/SC-55 Synth Bass 1.dmp
Normal file
BIN
instruments/FM/bass/SC-55 Synth Bass 1.dmp
Normal file
Binary file not shown.
BIN
instruments/FM/bass/SC-55 SynthBass101.dmp
Normal file
BIN
instruments/FM/bass/SC-55 SynthBass101.dmp
Normal file
Binary file not shown.
BIN
instruments/FM/bass/Yamaha MU Synth Bass 2.dmp
Normal file
BIN
instruments/FM/bass/Yamaha MU Synth Bass 2.dmp
Normal file
Binary file not shown.
BIN
instruments/FM/effect/Acoustic String Slap SFX.dmp
Normal file
BIN
instruments/FM/effect/Acoustic String Slap SFX.dmp
Normal file
Binary file not shown.
BIN
instruments/other/(AY) Closed Hat.fui
Normal file
BIN
instruments/other/(AY) Closed Hat.fui
Normal file
Binary file not shown.
BIN
instruments/other/(AY) Hat-EnvBass.fui
Normal file
BIN
instruments/other/(AY) Hat-EnvBass.fui
Normal file
Binary file not shown.
BIN
instruments/other/(AY) Kick E-1.fui
Normal file
BIN
instruments/other/(AY) Kick E-1.fui
Normal file
Binary file not shown.
BIN
instruments/other/(AY) Open Hat.fui
Normal file
BIN
instruments/other/(AY) Open Hat.fui
Normal file
Binary file not shown.
BIN
instruments/other/(AY) Snare A#3.fui
Normal file
BIN
instruments/other/(AY) Snare A#3.fui
Normal file
Binary file not shown.
|
@ -22,6 +22,7 @@ this is a list of systems that Furnace supports, including each system's effects
|
||||||
- [Philips SAA1099](saa1099.md)
|
- [Philips SAA1099](saa1099.md)
|
||||||
- [Microchip AY8930](ay8930.md)
|
- [Microchip AY8930](ay8930.md)
|
||||||
- [VERA](vera.md)
|
- [VERA](vera.md)
|
||||||
|
- [tildearrow Sound Unit](soundunit.md)
|
||||||
- [Seta/Allumer X1-010](x1-010.md)
|
- [Seta/Allumer X1-010](x1-010.md)
|
||||||
- [WonderSwan](wonderswan.md)
|
- [WonderSwan](wonderswan.md)
|
||||||
- [Bubble System WSG](bubblesystem.md)
|
- [Bubble System WSG](bubblesystem.md)
|
||||||
|
|
45
papers/doc/7-systems/soundunit.md
Normal file
45
papers/doc/7-systems/soundunit.md
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
# tildearrow Sound Unit
|
||||||
|
This is a fantasy sound chip, used in the specs2 fantasy computer designed by tildearrow. It includes native support for sample playback, but with only 8KB of sample data. Since 0.6pre1, this sound chip is no longer hidden by default and can be accessed through the module creation screen and can be added or removed.
|
||||||
|
|
||||||
|
# effects
|
||||||
|
|
||||||
|
- `10xx`: set waveform
|
||||||
|
- 0: pulse wave
|
||||||
|
- 1: sawtooth
|
||||||
|
- 2: sine wave
|
||||||
|
- 3: triangle wave
|
||||||
|
- 4: noise
|
||||||
|
- 5: periodic noise
|
||||||
|
- 6: XOR sine
|
||||||
|
- 7: XOR triangle
|
||||||
|
- `12xx`: set waveform (0 to 7F)
|
||||||
|
- `13xx`: set resonance of filter (0 to FF)
|
||||||
|
- despite what the internal effects list says (0 to F), you can use a resonance value from 0 to FF (255)
|
||||||
|
- `14xx`: set filter mode and ringmod
|
||||||
|
- bit 0: ring mod
|
||||||
|
- bit 1: low pass
|
||||||
|
- bit 2: high pass
|
||||||
|
- bit 3: band pass
|
||||||
|
- `15xx`: set frequency sweep period low byte
|
||||||
|
- `16xx`: set frequency sweep period high byte
|
||||||
|
- `17xx`: set volume sweep period low byte
|
||||||
|
- `18xx`: set volume sweep period high byte
|
||||||
|
- `19xx`: set cutoff sweep period low byte
|
||||||
|
- `1Axx`: set cutoff sweep period low byte
|
||||||
|
- `1Bxx`: set frequency sweep boundary
|
||||||
|
- `1Cxx`: set volume sweep boundary
|
||||||
|
- `1Dxx`: set cutoff sweep boundary
|
||||||
|
- `1Exx`: set phase reset period low byte
|
||||||
|
- `1Fxx`: set phase reset period high byte
|
||||||
|
- `20xx`: toggle frequency sweep
|
||||||
|
- bit 0-6: speed
|
||||||
|
- bit 7: up direction
|
||||||
|
- `21xx`: toggle volume sweep
|
||||||
|
- bit 0-4: speed
|
||||||
|
- bit 5: up direction
|
||||||
|
- bit 6: loop
|
||||||
|
- bit 7: alternate
|
||||||
|
- `22xx`: toggle cutoff sweep
|
||||||
|
- bit 0-6: speed
|
||||||
|
- bit 7: up direction
|
||||||
|
- `4xxx`: set cutoff (0 to FFF)
|
|
@ -32,6 +32,7 @@ these fields are 0 in format versions prior to 100 (0.6pre1).
|
||||||
|
|
||||||
the format versions are:
|
the format versions are:
|
||||||
|
|
||||||
|
- 101: Furnace 0.6pre1 (dev101)
|
||||||
- 100: Furnace 0.6pre1
|
- 100: Furnace 0.6pre1
|
||||||
- 99: Furnace dev99
|
- 99: Furnace dev99
|
||||||
- 98: Furnace dev98
|
- 98: Furnace dev98
|
||||||
|
@ -235,6 +236,8 @@ size | description
|
||||||
| - 0xbc: reserved - 8 channels
|
| - 0xbc: reserved - 8 channels
|
||||||
| - 0xbd: YM2612 extra features extended - 11 channels
|
| - 0xbd: YM2612 extra features extended - 11 channels
|
||||||
| - 0xbe: YM2612 extra features - 7 channels
|
| - 0xbe: YM2612 extra features - 7 channels
|
||||||
|
| - 0xbf: T6W28 - 4 channels
|
||||||
|
| - 0xc0: PCM DAC - 1 channel
|
||||||
| - 0xde: YM2610B extended - 19 channels
|
| - 0xde: YM2610B extended - 19 channels
|
||||||
| - 0xe0: QSound - 19 channels
|
| - 0xe0: QSound - 19 channels
|
||||||
| - 0xfd: Dummy System - 8 channels
|
| - 0xfd: Dummy System - 8 channels
|
||||||
|
@ -316,7 +319,8 @@ size | description
|
||||||
1 | volume macro still applies after end (>=99) or reserved
|
1 | volume macro still applies after end (>=99) or reserved
|
||||||
1 | broken outVol (>=99) or reserved
|
1 | broken outVol (>=99) or reserved
|
||||||
1 | E1xy and E2xy stop on same note (>=100) or reserved
|
1 | E1xy and E2xy stop on same note (>=100) or reserved
|
||||||
8 | reserved
|
1 | broken initial position of porta after arp (>=101) or reserved
|
||||||
|
7 | reserved
|
||||||
--- | **virtual tempo data**
|
--- | **virtual tempo data**
|
||||||
2 | virtual tempo numerator of first song (>=96) or reserved
|
2 | virtual tempo numerator of first song (>=96) or reserved
|
||||||
2 | virtual tempo denominator of first song (>=96) or reserved
|
2 | virtual tempo denominator of first song (>=96) or reserved
|
||||||
|
|
|
@ -45,8 +45,8 @@
|
||||||
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
||||||
#define BUSY_END isBusy.unlock(); softLocked=false;
|
#define BUSY_END isBusy.unlock(); softLocked=false;
|
||||||
|
|
||||||
#define DIV_VERSION "0.6pre1"
|
#define DIV_VERSION "0.6pre1 (dev101)"
|
||||||
#define DIV_ENGINE_VERSION 100
|
#define DIV_ENGINE_VERSION 101
|
||||||
|
|
||||||
// for imports
|
// for imports
|
||||||
#define DIV_VERSION_MOD 0xff01
|
#define DIV_VERSION_MOD 0xff01
|
||||||
|
|
|
@ -172,6 +172,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
ds.volMacroLinger=false;
|
ds.volMacroLinger=false;
|
||||||
ds.brokenOutVol=true; // ???
|
ds.brokenOutVol=true; // ???
|
||||||
ds.e1e2StopOnSameNote=true;
|
ds.e1e2StopOnSameNote=true;
|
||||||
|
ds.brokenPortaArp=false;
|
||||||
|
|
||||||
// 1.1 compat flags
|
// 1.1 compat flags
|
||||||
if (ds.version>24) {
|
if (ds.version>24) {
|
||||||
|
@ -1047,6 +1048,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
if (ds.version<100) {
|
if (ds.version<100) {
|
||||||
ds.e1e2StopOnSameNote=false;
|
ds.e1e2StopOnSameNote=false;
|
||||||
}
|
}
|
||||||
|
if (ds.version<101) {
|
||||||
|
ds.brokenPortaArp=true;
|
||||||
|
}
|
||||||
ds.isDMF=false;
|
ds.isDMF=false;
|
||||||
|
|
||||||
reader.readS(); // reserved
|
reader.readS(); // reserved
|
||||||
|
@ -1448,7 +1452,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
} else {
|
} else {
|
||||||
reader.readC();
|
reader.readC();
|
||||||
}
|
}
|
||||||
for (int i=0; i<8; i++) {
|
if (ds.version>=101) {
|
||||||
|
ds.brokenPortaArp=reader.readC();
|
||||||
|
} else {
|
||||||
|
reader.readC();
|
||||||
|
}
|
||||||
|
for (int i=0; i<7; i++) {
|
||||||
reader.readC();
|
reader.readC();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2922,7 +2931,8 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
||||||
w->writeC(song.volMacroLinger);
|
w->writeC(song.volMacroLinger);
|
||||||
w->writeC(song.brokenOutVol);
|
w->writeC(song.brokenOutVol);
|
||||||
w->writeC(song.e1e2StopOnSameNote);
|
w->writeC(song.e1e2StopOnSameNote);
|
||||||
for (int i=0; i<8; i++) {
|
w->writeC(song.brokenPortaArp);
|
||||||
|
for (int i=0; i<7; i++) {
|
||||||
w->writeC(0);
|
w->writeC(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -355,6 +355,7 @@ int DivPlatformAmiga::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_SAMPLE_POS:
|
case DIV_CMD_SAMPLE_POS:
|
||||||
|
|
|
@ -827,6 +827,7 @@ int DivPlatformArcade::dispatch(DivCommand c) {
|
||||||
return 127;
|
return 127;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_PORTA:
|
case DIV_CMD_PRE_PORTA:
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_LINEAR(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_NOTE:
|
case DIV_CMD_PRE_NOTE:
|
||||||
|
|
|
@ -471,9 +471,12 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
|
||||||
return 15;
|
return 15;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_PORTA:
|
case DIV_CMD_PRE_PORTA:
|
||||||
|
// TODO: FIX wtr_envelope.dmf
|
||||||
|
// the brokenPortaArp update broke it
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AY));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AY));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_NOTE:
|
case DIV_CMD_PRE_NOTE:
|
||||||
|
|
|
@ -506,6 +506,7 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AY8930));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AY8930));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_NOTE:
|
case DIV_CMD_PRE_NOTE:
|
||||||
|
|
|
@ -250,6 +250,7 @@ int DivPlatformBubSysWSG::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SCC));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SCC));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -369,6 +369,7 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
||||||
chan[c.chan].keyOn=true;
|
chan[c.chan].keyOn=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_NOTE:
|
case DIV_CMD_PRE_NOTE:
|
||||||
|
|
|
@ -406,6 +406,7 @@ int DivPlatformFDS::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_FDS));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_FDS));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -393,6 +393,7 @@ int DivPlatformGB::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_GB));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_GB));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GB_SWEEP_DIR:
|
case DIV_CMD_GB_SWEEP_DIR:
|
||||||
|
|
|
@ -387,6 +387,7 @@ int DivPlatformLynx::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_MIKEY));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_MIKEY));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -324,6 +324,7 @@ int DivPlatformMMC5::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -121,6 +121,7 @@ int DivPlatformMSM6258::dispatch(DivCommand c) {
|
||||||
chan[c.chan].outVol=chan[c.chan].vol;
|
chan[c.chan].outVol=chan[c.chan].vol;
|
||||||
}
|
}
|
||||||
sample=ins->amiga.getSample(c.value);
|
sample=ins->amiga.getSample(c.value);
|
||||||
|
samplePos=0;
|
||||||
if (sample>=0 && sample<parent->song.sampleLen) {
|
if (sample>=0 && sample<parent->song.sampleLen) {
|
||||||
//DivSample* s=parent->getSample(chan[c.chan].sample);
|
//DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
|
@ -144,8 +145,8 @@ int DivPlatformMSM6258::dispatch(DivCommand c) {
|
||||||
//DivSample* s=parent->getSample(12*sampleBank+c.value%12);
|
//DivSample* s=parent->getSample(12*sampleBank+c.value%12);
|
||||||
sample=12*sampleBank+c.value%12;
|
sample=12*sampleBank+c.value%12;
|
||||||
samplePos=0;
|
samplePos=0;
|
||||||
msm->ctrl_w(1);
|
rWrite(0,1);
|
||||||
msm->ctrl_w(2);
|
rWrite(0,2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -562,6 +562,7 @@ int DivPlatformN163::dispatch(DivCommand c) {
|
||||||
chan[c.chan].keyOn=true;
|
chan[c.chan].keyOn=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -442,6 +442,7 @@ int DivPlatformNamcoWSG::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_PCE));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_PCE));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -573,6 +573,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -1434,6 +1434,9 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
||||||
return 63;
|
return 63;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_PORTA:
|
case DIV_CMD_PRE_PORTA:
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) {
|
||||||
|
chan[c.chan].baseFreq=(c.chan==adpcmChan)?(NOTE_ADPCMB(chan[c.chan].note)):(NOTE_FREQUENCY(chan[c.chan].note));
|
||||||
|
}
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_NOTE:
|
case DIV_CMD_PRE_NOTE:
|
||||||
|
@ -1539,7 +1542,7 @@ void DivPlatformOPL::reset() {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if (downsample) {
|
if (downsample) {
|
||||||
const unsigned int downsampledRate=(unsigned int)(49716.0*(double(rate)/chipRateBase));
|
const unsigned int downsampledRate=(unsigned int)((double)rate*rate/chipRateBase);
|
||||||
OPL3_Reset(&fm,downsampledRate);
|
OPL3_Reset(&fm,downsampledRate);
|
||||||
} else {
|
} else {
|
||||||
OPL3_Reset(&fm,rate);
|
OPL3_Reset(&fm,rate);
|
||||||
|
@ -1669,7 +1672,7 @@ void DivPlatformOPL::setOPLType(int type, bool drums) {
|
||||||
slots=drums?slotsDrums:slotsNonDrums;
|
slots=drums?slotsDrums:slotsNonDrums;
|
||||||
chanMap=drums?chanMapOPL2Drums:chanMapOPL2;
|
chanMap=drums?chanMapOPL2Drums:chanMapOPL2;
|
||||||
outChanMap=outChanMapOPL2;
|
outChanMap=outChanMapOPL2;
|
||||||
chipFreqBase=9440540*0.25;
|
chipFreqBase=32768*72;
|
||||||
chans=9;
|
chans=9;
|
||||||
melodicChans=drums?6:9;
|
melodicChans=drums?6:9;
|
||||||
totalChans=drums?11:9;
|
totalChans=drums?11:9;
|
||||||
|
@ -1683,7 +1686,7 @@ void DivPlatformOPL::setOPLType(int type, bool drums) {
|
||||||
slots=drums?slotsDrums:slotsNonDrums;
|
slots=drums?slotsDrums:slotsNonDrums;
|
||||||
chanMap=drums?chanMapOPL3Drums:chanMapOPL3;
|
chanMap=drums?chanMapOPL3Drums:chanMapOPL3;
|
||||||
outChanMap=outChanMapOPL3;
|
outChanMap=outChanMapOPL3;
|
||||||
chipFreqBase=9440540;
|
chipFreqBase=32768*288;
|
||||||
chans=18;
|
chans=18;
|
||||||
melodicChans=drums?15:18;
|
melodicChans=drums?15:18;
|
||||||
totalChans=drums?20:18;
|
totalChans=drums?20:18;
|
||||||
|
@ -1735,9 +1738,6 @@ void DivPlatformOPL::setFlags(unsigned int flags) {
|
||||||
default:
|
default:
|
||||||
case 1: case 2: case 8950:
|
case 1: case 2: case 8950:
|
||||||
switch (flags&0xff) {
|
switch (flags&0xff) {
|
||||||
case 0x00:
|
|
||||||
chipClock=COLOR_NTSC;
|
|
||||||
break;
|
|
||||||
case 0x01:
|
case 0x01:
|
||||||
chipClock=COLOR_PAL*4.0/5.0;
|
chipClock=COLOR_PAL*4.0/5.0;
|
||||||
break;
|
break;
|
||||||
|
@ -1753,15 +1753,15 @@ void DivPlatformOPL::setFlags(unsigned int flags) {
|
||||||
case 0x05:
|
case 0x05:
|
||||||
chipClock=3500000.0;
|
chipClock=3500000.0;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
chipClock=COLOR_NTSC;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
rate=chipClock/72;
|
rate=chipClock/72;
|
||||||
chipRateBase=double(rate);
|
chipRateBase=rate;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
switch (flags&0xff) {
|
switch (flags&0xff) {
|
||||||
case 0x00:
|
|
||||||
chipClock=COLOR_NTSC*4.0;
|
|
||||||
break;
|
|
||||||
case 0x01:
|
case 0x01:
|
||||||
chipClock=COLOR_PAL*16.0/5.0;
|
chipClock=COLOR_PAL*16.0/5.0;
|
||||||
break;
|
break;
|
||||||
|
@ -1774,28 +1774,31 @@ void DivPlatformOPL::setFlags(unsigned int flags) {
|
||||||
case 0x04:
|
case 0x04:
|
||||||
chipClock=15000000.0;
|
chipClock=15000000.0;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
chipClock=COLOR_NTSC*4.0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
rate=chipClock/288;
|
rate=chipClock/288;
|
||||||
chipRateBase=double(rate);
|
chipRateBase=rate;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
switch (flags&0xff) {
|
switch (flags&0xff) {
|
||||||
case 0x02:
|
|
||||||
chipClock=33868800.0;
|
|
||||||
break;
|
|
||||||
case 0x00:
|
|
||||||
chipClock=COLOR_NTSC*8.0;
|
|
||||||
break;
|
|
||||||
case 0x01:
|
case 0x01:
|
||||||
chipClock=COLOR_PAL*32.0/5.0;
|
chipClock=COLOR_PAL*32.0/5.0;
|
||||||
break;
|
break;
|
||||||
|
case 0x02:
|
||||||
|
chipClock=33868800.0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
chipClock=COLOR_NTSC*8.0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
chipRateBase=double(chipClock)/684.0;
|
|
||||||
rate=chipClock/768;
|
rate=chipClock/768;
|
||||||
|
chipRateBase=chipClock/684;
|
||||||
break;
|
break;
|
||||||
case 759:
|
case 759:
|
||||||
rate=48000;
|
rate=48000;
|
||||||
chipRateBase=double(rate);
|
chipRateBase=rate;
|
||||||
chipClock=rate*288;
|
chipClock=rate*288;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ class DivPlatformOPL: public DivDispatch {
|
||||||
const unsigned char** slots;
|
const unsigned char** slots;
|
||||||
const unsigned short* chanMap;
|
const unsigned short* chanMap;
|
||||||
const unsigned char* outChanMap;
|
const unsigned char* outChanMap;
|
||||||
double chipFreqBase, chipRateBase;
|
int chipFreqBase, chipRateBase;
|
||||||
int delay, chipType, oplType, chans, melodicChans, totalChans, adpcmChan, sampleBank;
|
int delay, chipType, oplType, chans, melodicChans, totalChans, adpcmChan, sampleBank;
|
||||||
unsigned char lastBusy;
|
unsigned char lastBusy;
|
||||||
unsigned char drumState;
|
unsigned char drumState;
|
||||||
|
|
|
@ -831,6 +831,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_PORTA:
|
case DIV_CMD_PRE_PORTA:
|
||||||
if (c.chan>=9 && !properDrums) return 0;
|
if (c.chan>=9 && !properDrums) return 0;
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_NOTE:
|
case DIV_CMD_PRE_NOTE:
|
||||||
|
|
|
@ -445,6 +445,7 @@ int DivPlatformPCE::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_PCE));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_PCE));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -471,6 +471,7 @@ int DivPlatformPCSpeaker::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_BEEPER));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_BEEPER));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -239,6 +239,7 @@ int DivPlatformPET::dispatch(DivCommand c) {
|
||||||
if (chan.active && c.value2) {
|
if (chan.active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan.macroInit(parent->getIns(chan.ins,DIV_INS_PET));
|
if (parent->song.resetMacroOnPorta) chan.macroInit(parent->getIns(chan.ins,DIV_INS_PET));
|
||||||
}
|
}
|
||||||
|
if (!chan.inPorta && c.value && !parent->song.brokenPortaArp && chan.std.arp.will) chan.baseFreq=NOTE_PERIODIC(chan.note);
|
||||||
chan.inPorta=c.value;
|
chan.inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -496,6 +496,7 @@ int DivPlatformQSound::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=QS_NOTE_FREQUENCY(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -265,6 +265,7 @@ int DivPlatformRF5C68::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_SAMPLE_POS:
|
case DIV_CMD_SAMPLE_POS:
|
||||||
|
|
|
@ -335,6 +335,7 @@ int DivPlatformSAA1099::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SAA1099));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SAA1099));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_NOTE:
|
case DIV_CMD_PRE_NOTE:
|
||||||
|
|
|
@ -267,6 +267,7 @@ int DivPlatformSCC::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SCC));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SCC));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -365,6 +365,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
|
||||||
return 127;
|
return 127;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_PORTA:
|
case DIV_CMD_PRE_PORTA:
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=(chan[c.chan].note<<6);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_NOTE:
|
case DIV_CMD_PRE_NOTE:
|
||||||
|
|
|
@ -133,7 +133,7 @@ void DivPlatformSMS::tick(bool sysTick) {
|
||||||
if (i==3) CHIP_DIVIDER=noiseDivider;
|
if (i==3) CHIP_DIVIDER=noiseDivider;
|
||||||
chan[i].std.next();
|
chan[i].std.next();
|
||||||
if (chan[i].std.vol.had) {
|
if (chan[i].std.vol.had) {
|
||||||
chan[i].outVol=MIN(15,chan[i].std.vol.val)-(15-(chan[i].vol&15));
|
chan[i].outVol=VOL_SCALE_LOG(chan[i].std.vol.val,chan[i].vol,15);
|
||||||
if (chan[i].outVol<0) chan[i].outVol=0;
|
if (chan[i].outVol<0) chan[i].outVol=0;
|
||||||
// old formula
|
// old formula
|
||||||
// ((chan[i].vol&15)*MIN(15,chan[i].std.vol.val))>>4;
|
// ((chan[i].vol&15)*MIN(15,chan[i].std.vol.val))>>4;
|
||||||
|
@ -353,9 +353,8 @@ int DivPlatformSMS::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
// TODO: pre porta cancel arp compat flag
|
|
||||||
//if (chan[c.chan].inPorta) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
return 15;
|
return 15;
|
||||||
|
|
|
@ -454,6 +454,7 @@ int DivPlatformSoundUnit::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SU));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SU));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -431,6 +431,7 @@ int DivPlatformSwan::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SWAN));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SWAN));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -259,6 +259,7 @@ int DivPlatformTIA::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_TIA));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_TIA));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=(chan[c.chan].note<<8);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_NOTE:
|
case DIV_CMD_PRE_NOTE:
|
||||||
|
|
|
@ -933,6 +933,7 @@ int DivPlatformTX81Z::dispatch(DivCommand c) {
|
||||||
return 127;
|
return 127;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_PORTA:
|
case DIV_CMD_PRE_PORTA:
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_LINEAR(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_NOTE:
|
case DIV_CMD_PRE_NOTE:
|
||||||
|
|
|
@ -361,6 +361,7 @@ int DivPlatformVERA::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_VERA));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_VERA));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=calcNoteFreq(c.chan,chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_STD_NOISE_MODE:
|
case DIV_CMD_STD_NOISE_MODE:
|
||||||
|
|
|
@ -243,6 +243,7 @@ int DivPlatformVIC20::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_VIC));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_VIC));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -399,6 +399,7 @@ int DivPlatformVRC6::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_VRC6));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_VRC6));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -732,6 +732,7 @@ int DivPlatformX1_010::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_X1_010));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_X1_010));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NoteX1_010(c.chan,chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_SAMPLE_FREQ:
|
case DIV_CMD_SAMPLE_FREQ:
|
||||||
|
|
|
@ -293,6 +293,7 @@ int DivPlatformYMZ280B::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_SAMPLE_POS:
|
case DIV_CMD_SAMPLE_POS:
|
||||||
|
|
|
@ -224,6 +224,7 @@ int DivPlatformZXBeeper::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_BEEPER));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_BEEPER));
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
|
|
|
@ -334,6 +334,11 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
if (chan[i].lastIns!=pat->data[whatRow][2]) {
|
if (chan[i].lastIns!=pat->data[whatRow][2]) {
|
||||||
chan[i].lastIns=pat->data[whatRow][2];
|
chan[i].lastIns=pat->data[whatRow][2];
|
||||||
insChanged=true;
|
insChanged=true;
|
||||||
|
if (song.legacyVolumeSlides && chan[i].volume==chan[i].volMax+1) {
|
||||||
|
logV("forcing volume");
|
||||||
|
chan[i].volume=chan[i].volMax;
|
||||||
|
dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// note
|
// note
|
||||||
|
|
|
@ -114,6 +114,8 @@ enum DivSystem {
|
||||||
DIV_SYSTEM_YM2612_FRAC,
|
DIV_SYSTEM_YM2612_FRAC,
|
||||||
DIV_SYSTEM_YM2612_FRAC_EXT,
|
DIV_SYSTEM_YM2612_FRAC_EXT,
|
||||||
DIV_SYSTEM_RESERVED_8,
|
DIV_SYSTEM_RESERVED_8,
|
||||||
|
DIV_SYSTEM_T6W28,
|
||||||
|
DIV_SYSTEM_PCM_DAC,
|
||||||
DIV_SYSTEM_DUMMY
|
DIV_SYSTEM_DUMMY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -351,7 +353,7 @@ struct DivSong {
|
||||||
// - 1: stereo
|
// - 1: stereo
|
||||||
// - YM2203:
|
// - YM2203:
|
||||||
// - bit 0-4: clock rate
|
// - bit 0-4: clock rate
|
||||||
// - 0: 3.58MHz (MTSC)
|
// - 0: 3.58MHz (NTSC)
|
||||||
// - 1: 3.55MHz (PAL)
|
// - 1: 3.55MHz (PAL)
|
||||||
// - 2: 4MHz
|
// - 2: 4MHz
|
||||||
// - 3: 3MHz
|
// - 3: 3MHz
|
||||||
|
@ -371,7 +373,7 @@ struct DivSong {
|
||||||
// - 2: FM: clock / 48, SSG: clock / 8
|
// - 2: FM: clock / 48, SSG: clock / 8
|
||||||
// - YM3526, YM3812, Y8950:
|
// - YM3526, YM3812, Y8950:
|
||||||
// - bit 0-7: clock rate
|
// - bit 0-7: clock rate
|
||||||
// - 0: 3.58MHz (MTSC)
|
// - 0: 3.58MHz (NTSC)
|
||||||
// - 1: 3.55MHz (PAL)
|
// - 1: 3.55MHz (PAL)
|
||||||
// - 2: 4MHz
|
// - 2: 4MHz
|
||||||
// - 3: 3MHz
|
// - 3: 3MHz
|
||||||
|
@ -379,7 +381,7 @@ struct DivSong {
|
||||||
// - 5: 3.5MHz
|
// - 5: 3.5MHz
|
||||||
// - YMF262:
|
// - YMF262:
|
||||||
// - bit 0-7: clock rate
|
// - bit 0-7: clock rate
|
||||||
// - 0: 14.32MHz (MTSC)
|
// - 0: 14.32MHz (NTSC)
|
||||||
// - 1: 14.19MHz (PAL)
|
// - 1: 14.19MHz (PAL)
|
||||||
// - 2: 14MHz
|
// - 2: 14MHz
|
||||||
// - 3: 16MHz
|
// - 3: 16MHz
|
||||||
|
@ -387,7 +389,7 @@ struct DivSong {
|
||||||
// - YMF289B: (TODO)
|
// - YMF289B: (TODO)
|
||||||
// - bit 0-7: clock rate
|
// - bit 0-7: clock rate
|
||||||
// - 0: 33.8688MHz
|
// - 0: 33.8688MHz
|
||||||
// - 1: 28.64MHz (MTSC)
|
// - 1: 28.64MHz (NTSC)
|
||||||
// - 2: 28.38MHz (PAL)
|
// - 2: 28.38MHz (PAL)
|
||||||
// - MSM6295:
|
// - MSM6295:
|
||||||
// - bit 0-6: clock rate
|
// - bit 0-6: clock rate
|
||||||
|
@ -418,7 +420,7 @@ struct DivSong {
|
||||||
// - YMZ280B:
|
// - YMZ280B:
|
||||||
// - bit 0-7: clock rate
|
// - bit 0-7: clock rate
|
||||||
// - 0: 16.9344MHz
|
// - 0: 16.9344MHz
|
||||||
// - 1: 14.32MHz (MTSC)
|
// - 1: 14.32MHz (NTSC)
|
||||||
// - 2: 14.19MHz (PAL)
|
// - 2: 14.19MHz (PAL)
|
||||||
// - 3: 16MHz
|
// - 3: 16MHz
|
||||||
// - 4: 16.67MHz
|
// - 4: 16.67MHz
|
||||||
|
@ -495,6 +497,7 @@ struct DivSong {
|
||||||
bool volMacroLinger;
|
bool volMacroLinger;
|
||||||
bool brokenOutVol;
|
bool brokenOutVol;
|
||||||
bool e1e2StopOnSameNote;
|
bool e1e2StopOnSameNote;
|
||||||
|
bool brokenPortaArp;
|
||||||
|
|
||||||
std::vector<DivInstrument*> ins;
|
std::vector<DivInstrument*> ins;
|
||||||
std::vector<DivWavetable*> wave;
|
std::vector<DivWavetable*> wave;
|
||||||
|
@ -593,7 +596,8 @@ struct DivSong {
|
||||||
newVolumeScaling(true),
|
newVolumeScaling(true),
|
||||||
volMacroLinger(true),
|
volMacroLinger(true),
|
||||||
brokenOutVol(false),
|
brokenOutVol(false),
|
||||||
e1e2StopOnSameNote(false) {
|
e1e2StopOnSameNote(false),
|
||||||
|
brokenPortaArp(false) {
|
||||||
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;
|
systemVol[i]=64;
|
||||||
|
|
|
@ -165,25 +165,25 @@ String DivEngine::getSongSystemName(bool isMultiSystemAcceptable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_VRC6) {
|
if (song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_VRC6) {
|
||||||
return "NES + Konami VRC6";
|
return "Famicom + Konami VRC6";
|
||||||
}
|
}
|
||||||
if (song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_VRC7) {
|
if (song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_VRC7) {
|
||||||
return "NES + Konami VRC7";
|
return "Famicom + Konami VRC7";
|
||||||
}
|
}
|
||||||
if (song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_OPLL) {
|
if (song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_OPLL) {
|
||||||
return "NES + Yamaha OPLL";
|
return "Family Noraebang";
|
||||||
}
|
}
|
||||||
if (song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_FDS) {
|
if (song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_FDS) {
|
||||||
return "Famicom Disk System";
|
return "Famicom Disk System";
|
||||||
}
|
}
|
||||||
if (song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_N163) {
|
if (song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_N163) {
|
||||||
return "NES + Namco C163";
|
return "Famicom + Namco C163";
|
||||||
}
|
}
|
||||||
if (song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_MMC5) {
|
if (song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_MMC5) {
|
||||||
return "NES + MMC5";
|
return "Famicom + MMC5";
|
||||||
}
|
}
|
||||||
if (song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_AY8910) {
|
if (song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_AY8910) {
|
||||||
return "NES + Sunsoft 5B";
|
return "Famicom + Sunsoft 5B";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (song.system[0]==DIV_SYSTEM_AY8910 && song.system[1]==DIV_SYSTEM_AY8910) {
|
if (song.system[0]==DIV_SYSTEM_AY8910 && song.system[1]==DIV_SYSTEM_AY8910) {
|
||||||
|
@ -2082,6 +2082,35 @@ void DivEngine::registerSystems() {
|
||||||
fmPostEffectHandler
|
fmPostEffectHandler
|
||||||
);
|
);
|
||||||
|
|
||||||
|
sysDefs[DIV_SYSTEM_T6W28]=new DivSysDef(
|
||||||
|
"T6W28", NULL, 0xbf, 0, 4, false, true, 0, false,
|
||||||
|
"an SN76489 derivative used in Neo Geo Pocket, has independent stereo volume and noise channel frequency.",
|
||||||
|
{"Square 1", "Square 2", "Square 3", "Noise"},
|
||||||
|
{"S1", "S2", "S3", "NO"},
|
||||||
|
{DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_NOISE},
|
||||||
|
{DIV_INS_STD, DIV_INS_STD, DIV_INS_STD, DIV_INS_STD},
|
||||||
|
{},
|
||||||
|
[this](int ch, unsigned char effect, unsigned char effectVal) -> bool {
|
||||||
|
switch (effect) {
|
||||||
|
case 0x20: // SN noise mode
|
||||||
|
dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
sysDefs[DIV_SYSTEM_PCM_DAC]=new DivSysDef(
|
||||||
|
"Generic PCM DAC", NULL, 0xc0, 0, 1, false, true, 0, false,
|
||||||
|
"as generic sample playback as it gets.",
|
||||||
|
{"Sample"},
|
||||||
|
{"PCM"},
|
||||||
|
{DIV_CH_PCM},
|
||||||
|
{DIV_INS_AMIGA}
|
||||||
|
);
|
||||||
|
|
||||||
sysDefs[DIV_SYSTEM_DUMMY]=new DivSysDef(
|
sysDefs[DIV_SYSTEM_DUMMY]=new DivSysDef(
|
||||||
"Dummy System", NULL, 0xfd, 0, 8, false, true, 0, false,
|
"Dummy System", NULL, 0xfd, 0, 8, false, true, 0, false,
|
||||||
"this is a system designed for testing purposes.",
|
"this is a system designed for testing purposes.",
|
||||||
|
|
|
@ -207,31 +207,35 @@ void FurnaceGUI::drawCompatFlags() {
|
||||||
}
|
}
|
||||||
ImGui::Checkbox("Stop portamento on note off",&e->song.stopPortaOnNoteOff);
|
ImGui::Checkbox("Stop portamento on note off",&e->song.stopPortaOnNoteOff);
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("behavior changed in 0.6");
|
ImGui::SetTooltip("behavior changed in 0.6pre1");
|
||||||
}
|
}
|
||||||
ImGui::Checkbox("Allow instrument change during slides",&e->song.newInsTriggersInPorta);
|
ImGui::Checkbox("Allow instrument change during slides",&e->song.newInsTriggersInPorta);
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("behavior changed in 0.6");
|
ImGui::SetTooltip("behavior changed in 0.6pre1");
|
||||||
}
|
}
|
||||||
ImGui::Checkbox("Reset note to base on arpeggio stop",&e->song.arp0Reset);
|
ImGui::Checkbox("Reset note to base on arpeggio stop",&e->song.arp0Reset);
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("behavior changed in 0.6");
|
ImGui::SetTooltip("behavior changed in 0.6pre1");
|
||||||
}
|
}
|
||||||
ImGui::Checkbox("ExtCh channel status is shared among operators",&e->song.sharedExtStat);
|
ImGui::Checkbox("ExtCh channel status is shared among operators",&e->song.sharedExtStat);
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("behavior changed in 0.6");
|
ImGui::SetTooltip("behavior changed in 0.6pre1");
|
||||||
}
|
}
|
||||||
ImGui::Checkbox("New SegaPCM features (macros and better panning)",&e->song.newSegaPCM);
|
ImGui::Checkbox("New SegaPCM features (macros and better panning)",&e->song.newSegaPCM);
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("behavior changed in 0.6");
|
ImGui::SetTooltip("behavior changed in 0.6pre1");
|
||||||
}
|
}
|
||||||
ImGui::Checkbox("Old FM octave boundary behavior",&e->song.oldOctaveBoundary);
|
ImGui::Checkbox("Old FM octave boundary behavior",&e->song.oldOctaveBoundary);
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("behavior changed in 0.6");
|
ImGui::SetTooltip("behavior changed in 0.6pre1");
|
||||||
}
|
}
|
||||||
ImGui::Checkbox("No OPN2 DAC volume control",&e->song.noOPN2Vol);
|
ImGui::Checkbox("No OPN2 DAC volume control",&e->song.noOPN2Vol);
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("behavior changed in 0.6");
|
ImGui::SetTooltip("behavior changed in 0.6pre1");
|
||||||
|
}
|
||||||
|
ImGui::Checkbox("Broken initial position of portamento after arpeggio",&e->song.brokenPortaArp);
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip("behavior changed in 0.6pre1.5");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_COMPAT_FLAGS;
|
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_COMPAT_FLAGS;
|
||||||
|
|
|
@ -447,7 +447,6 @@ void FurnaceGUI::doReplace() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!us.pat.empty()) {
|
if (!us.pat.empty()) {
|
||||||
printf("pusher\n");
|
|
||||||
undoHist.push_back(us);
|
undoHist.push_back(us);
|
||||||
redoHist.clear();
|
redoHist.clear();
|
||||||
if (undoHist.size()>settings.maxUndoSteps) undoHist.pop_front();
|
if (undoHist.size()>settings.maxUndoSteps) undoHist.pop_front();
|
||||||
|
@ -997,16 +996,16 @@ void FurnaceGUI::drawFindReplace() {
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::BeginDisabled(!queryReplaceEffectValDo[i]);
|
ImGui::BeginDisabled(!queryReplaceEffectValDo[i]);
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
ImGui::Combo("##ERMode",&queryReplaceEffectValMode[i],queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
ImGui::Combo("##ERModeV",&queryReplaceEffectValMode[i],queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
if (queryReplaceEffectValMode[i]==GUI_QUERY_REPLACE_SET) {
|
if (queryReplaceEffectValMode[i]==GUI_QUERY_REPLACE_SET) {
|
||||||
if (ImGui::InputScalar("##ERValueH",ImGuiDataType_S32,&queryReplaceEffectVal[i],&_ONE,&_SIXTEEN,"%.2X",ImGuiInputTextFlags_CharsHexadecimal)) {
|
if (ImGui::InputScalar("##ERValueVH",ImGuiDataType_S32,&queryReplaceEffectVal[i],&_ONE,&_SIXTEEN,"%.2X",ImGuiInputTextFlags_CharsHexadecimal)) {
|
||||||
if (queryReplaceEffectVal[i]<0) queryReplaceEffectVal[i]=0;
|
if (queryReplaceEffectVal[i]<0) queryReplaceEffectVal[i]=0;
|
||||||
if (queryReplaceEffectVal[i]>255) queryReplaceEffectVal[i]=255;
|
if (queryReplaceEffectVal[i]>255) queryReplaceEffectVal[i]=255;
|
||||||
}
|
}
|
||||||
} else if (queryReplaceEffectValMode[i]==GUI_QUERY_REPLACE_ADD || queryReplaceEffectValMode[i]==GUI_QUERY_REPLACE_ADD_OVERFLOW) {
|
} else if (queryReplaceEffectValMode[i]==GUI_QUERY_REPLACE_ADD || queryReplaceEffectValMode[i]==GUI_QUERY_REPLACE_ADD_OVERFLOW) {
|
||||||
if (ImGui::InputInt("##ERValue",&queryReplaceEffectVal[i],1,12)) {
|
if (ImGui::InputInt("##ERValueV",&queryReplaceEffectVal[i],1,12)) {
|
||||||
if (queryReplaceEffectVal[i]<-255) queryReplaceEffectVal[i]=-255;
|
if (queryReplaceEffectVal[i]<-255) queryReplaceEffectVal[i]=-255;
|
||||||
if (queryReplaceEffectVal[i]>255) queryReplaceEffectVal[i]=255;
|
if (queryReplaceEffectVal[i]>255) queryReplaceEffectVal[i]=255;
|
||||||
}
|
}
|
||||||
|
|
|
@ -589,49 +589,49 @@ void FurnaceGUI::initSystemPresets() {
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
cat.systems.push_back(FurnaceGUISysDef(
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
"NES with Konami VRC6", {
|
"Famicom with Konami VRC6", {
|
||||||
DIV_SYSTEM_NES, 64, 0, 0,
|
DIV_SYSTEM_NES, 64, 0, 0,
|
||||||
DIV_SYSTEM_VRC6, 64, 0, 0,
|
DIV_SYSTEM_VRC6, 64, 0, 0,
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
cat.systems.push_back(FurnaceGUISysDef(
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
"NES with Konami VRC7", {
|
"Famicom with Konami VRC7", {
|
||||||
DIV_SYSTEM_NES, 64, 0, 0,
|
DIV_SYSTEM_NES, 64, 0, 0,
|
||||||
DIV_SYSTEM_VRC7, 64, 0, 0,
|
DIV_SYSTEM_VRC7, 64, 0, 0,
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
cat.systems.push_back(FurnaceGUISysDef(
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
"NES with MMC5", {
|
"Famicom with MMC5", {
|
||||||
DIV_SYSTEM_NES, 64, 0, 0,
|
DIV_SYSTEM_NES, 64, 0, 0,
|
||||||
DIV_SYSTEM_MMC5, 64, 0, 0,
|
DIV_SYSTEM_MMC5, 64, 0, 0,
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
cat.systems.push_back(FurnaceGUISysDef(
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
"NES with Sunsoft 5B", {
|
"Famicom with Sunsoft 5B", {
|
||||||
DIV_SYSTEM_NES, 64, 0, 0,
|
DIV_SYSTEM_NES, 64, 0, 0,
|
||||||
DIV_SYSTEM_AY8910, 64, 0, 32,
|
DIV_SYSTEM_AY8910, 64, 0, 32,
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
cat.systems.push_back(FurnaceGUISysDef(
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
"NES with Namco C163", {
|
"Famicom with Namco C163", {
|
||||||
DIV_SYSTEM_NES, 64, 0, 0,
|
DIV_SYSTEM_NES, 64, 0, 0,
|
||||||
DIV_SYSTEM_N163, 64, 0, 112,
|
DIV_SYSTEM_N163, 64, 0, 112,
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
cat.systems.push_back(FurnaceGUISysDef(
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
"NES with Family Noraebang", {
|
"Comboy with Family Noraebang", {
|
||||||
DIV_SYSTEM_NES, 64, 0, 0,
|
DIV_SYSTEM_NES, 64, 0, 0,
|
||||||
DIV_SYSTEM_OPLL, 64, 0, 0,
|
DIV_SYSTEM_OPLL, 64, 0, 0,
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
cat.systems.push_back(FurnaceGUISysDef(
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
"NES with Family Noraebang (drums mode)", {
|
"Comboy with Family Noraebang (drums mode)", {
|
||||||
DIV_SYSTEM_NES, 64, 0, 0,
|
DIV_SYSTEM_NES, 64, 0, 0,
|
||||||
DIV_SYSTEM_OPLL_DRUMS, 64, 0, 0,
|
DIV_SYSTEM_OPLL_DRUMS, 64, 0, 0,
|
||||||
0
|
0
|
||||||
|
@ -1282,6 +1282,29 @@ void FurnaceGUI::initSystemPresets() {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
|
"Sega System E", {
|
||||||
|
DIV_SYSTEM_SMS, 64, 0, 0,
|
||||||
|
DIV_SYSTEM_SMS, 64, 0, 0,
|
||||||
|
0
|
||||||
|
}
|
||||||
|
));
|
||||||
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
|
"Sega System E (with FM expansion)", {
|
||||||
|
DIV_SYSTEM_SMS, 64, 0, 0,
|
||||||
|
DIV_SYSTEM_SMS, 64, 0, 0,
|
||||||
|
DIV_SYSTEM_OPLL, 64, 0, 0,
|
||||||
|
0
|
||||||
|
}
|
||||||
|
));
|
||||||
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
|
"Sega System E (with FM expansion in drums mode)", {
|
||||||
|
DIV_SYSTEM_SMS, 64, 0, 0,
|
||||||
|
DIV_SYSTEM_SMS, 64, 0, 0,
|
||||||
|
DIV_SYSTEM_OPLL_DRUMS, 64, 0, 0,
|
||||||
|
0
|
||||||
|
}
|
||||||
|
));
|
||||||
cat.systems.push_back(FurnaceGUISysDef(
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
"Sega Hang-On", {
|
"Sega Hang-On", {
|
||||||
DIV_SYSTEM_OPN, 64, 0, 2, // 4MHz
|
DIV_SYSTEM_OPN, 64, 0, 2, // 4MHz
|
||||||
|
@ -2071,7 +2094,7 @@ void FurnaceGUI::initSystemPresets() {
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
cat.systems.push_back(FurnaceGUISysDef(
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
"NES with Konami VRC7", {
|
"Famicom with Konami VRC7", {
|
||||||
DIV_SYSTEM_NES, 64, 0, 0,
|
DIV_SYSTEM_NES, 64, 0, 0,
|
||||||
DIV_SYSTEM_VRC7, 64, 0, 0,
|
DIV_SYSTEM_VRC7, 64, 0, 0,
|
||||||
0
|
0
|
||||||
|
|
|
@ -569,7 +569,7 @@ void FurnaceGUI::drawSysConf(int chan, DivSystem type, unsigned int& flags, bool
|
||||||
case DIV_SYSTEM_OPL3:
|
case DIV_SYSTEM_OPL3:
|
||||||
case DIV_SYSTEM_OPL3_DRUMS: {
|
case DIV_SYSTEM_OPL3_DRUMS: {
|
||||||
ImGui::Text("Clock rate:");
|
ImGui::Text("Clock rate:");
|
||||||
if (ImGui::RadioButton("14.32MHz (MTSC)",(flags&255)==0)) {
|
if (ImGui::RadioButton("14.32MHz (NTSC)",(flags&255)==0)) {
|
||||||
copyOfFlags=(flags&(~255))|0;
|
copyOfFlags=(flags&(~255))|0;
|
||||||
}
|
}
|
||||||
if (ImGui::RadioButton("14.19MHz (PAL)",(flags&255)==1)) {
|
if (ImGui::RadioButton("14.19MHz (PAL)",(flags&255)==1)) {
|
||||||
|
@ -591,7 +591,7 @@ void FurnaceGUI::drawSysConf(int chan, DivSystem type, unsigned int& flags, bool
|
||||||
if (ImGui::RadioButton("16.9344MHz",(flags&255)==0)) {
|
if (ImGui::RadioButton("16.9344MHz",(flags&255)==0)) {
|
||||||
copyOfFlags=(flags&(~255))|0;
|
copyOfFlags=(flags&(~255))|0;
|
||||||
}
|
}
|
||||||
if (ImGui::RadioButton("14.32MHz (MTSC)",(flags&255)==1)) {
|
if (ImGui::RadioButton("14.32MHz (NTSC)",(flags&255)==1)) {
|
||||||
copyOfFlags=(flags&(~255))|1;
|
copyOfFlags=(flags&(~255))|1;
|
||||||
}
|
}
|
||||||
if (ImGui::RadioButton("14.19MHz (PAL)",(flags&255)==3)) {
|
if (ImGui::RadioButton("14.19MHz (PAL)",(flags&255)==3)) {
|
||||||
|
@ -608,12 +608,34 @@ void FurnaceGUI::drawSysConf(int chan, DivSystem type, unsigned int& flags, bool
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DIV_SYSTEM_PCM_DAC: {
|
||||||
|
int sampRate=(flags&65535)+1;
|
||||||
|
int bitDepth=((flags>>16)&15)+1;
|
||||||
|
bool stereo=(flags>>20)&1;
|
||||||
|
ImGui::Text("Output rate:");
|
||||||
|
if (CWSliderInt("##SampRate",&sampRate,1,65536)) {
|
||||||
|
if (sampRate<1) sampRate=1;
|
||||||
|
if (sampRate>65536) sampRate=65536;
|
||||||
|
copyOfFlags=(flags&(~65535))|(sampRate-1);
|
||||||
|
} rightClickable
|
||||||
|
ImGui::Text("Output depth:");
|
||||||
|
if (CWSliderInt("##BitDepth",&bitDepth,1,16)) {
|
||||||
|
if (bitDepth<1) bitDepth=1;
|
||||||
|
if (bitDepth>16) bitDepth=16;
|
||||||
|
copyOfFlags=(flags&(~(15<<16)))|((bitDepth-1)<<16);
|
||||||
|
} rightClickable
|
||||||
|
if (ImGui::Checkbox("Stereo",&stereo)) {
|
||||||
|
copyOfFlags=(flags&(~(1<<20)))|(stereo<<20);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DIV_SYSTEM_GB:
|
case DIV_SYSTEM_GB:
|
||||||
case DIV_SYSTEM_SWAN:
|
case DIV_SYSTEM_SWAN:
|
||||||
case DIV_SYSTEM_VERA:
|
case DIV_SYSTEM_VERA:
|
||||||
case DIV_SYSTEM_BUBSYS_WSG:
|
case DIV_SYSTEM_BUBSYS_WSG:
|
||||||
case DIV_SYSTEM_YMU759:
|
case DIV_SYSTEM_YMU759:
|
||||||
case DIV_SYSTEM_PET:
|
case DIV_SYSTEM_PET:
|
||||||
|
case DIV_SYSTEM_T6W28:
|
||||||
ImGui::Text("nothing to configure");
|
ImGui::Text("nothing to configure");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue