diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index fb9be5800..2fde9addd 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -417,13 +417,6 @@ class DivDispatch { */ virtual bool getWantPreNote(); - /** - * get a description of a dispatch-specific effect. - * @param effect the effect. - * @return the description, or NULL if effect is invalid. - */ - virtual const char* getEffectName(unsigned char effect); - /** * set the chip flags. * @param flags the flags. see song.h for possible values. diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 68c492219..5fe2db695 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -124,8 +124,15 @@ const char* DivEngine::getEffectDesc(unsigned char effect, int chan, bool notNul if ((effect&0xf0)==0x90) { return "9xxx: Set sample offset*256"; } else if (chan>=0 && changetEffectName(effect); - if (ret!=NULL) return ret; + DivSysDef* sysDef=sysDefs[sysOfChan[chan]]; + auto iter=sysDef->effectHandlers.find(effect); + if (iter!=sysDef->effectHandlers.end()) { + return iter->second.description; + } + iter=sysDef->postEffectHandlers.find(effect); + if (iter!=sysDef->postEffectHandlers.end()) { + return iter->second.description; + } } break; } diff --git a/src/engine/engine.h b/src/engine/engine.h index 3a73d7d24..191414f5f 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #define addWarning(x) \ @@ -194,7 +195,29 @@ struct DivDispatchContainer { dcOffCompensation(false) {} }; -typedef std::function EffectProcess; +typedef int EffectValConversion(unsigned char,unsigned char); + +struct EffectHandler { + DivDispatchCmds dispatchCmd; + const char* description; + EffectValConversion* val; + EffectValConversion* val2; + EffectHandler( + DivDispatchCmds dispatchCmd_, + const char* description_, + EffectValConversion val_=NULL, + EffectValConversion val2_=NULL + ): + dispatchCmd(dispatchCmd_), + description(description_), + val(val_), + val2(val2_) {} +}; + +struct DivDoNotHandleEffect { +}; + +typedef std::unordered_map EffectHandlerMap; struct DivSysDef { const char* name; @@ -211,8 +234,8 @@ struct DivSysDef { // 0: primary // 1: alternate (usually PCM) DivInstrumentType chanInsType[DIV_MAX_CHANS][2]; - EffectProcess effectFunc; - EffectProcess postEffectFunc; + const EffectHandlerMap effectHandlers; + const EffectHandlerMap postEffectHandlers; DivSysDef( const char* sysName, const char* sysNameJ, unsigned char fileID, unsigned char fileID_DMF, int chans, bool isFMChip, bool isSTDChip, unsigned int vgmVer, bool compound, const char* desc, @@ -221,8 +244,8 @@ struct DivSysDef { std::initializer_list chTypes, std::initializer_list chInsType1, std::initializer_list chInsType2={}, - EffectProcess fxHandler=[](int,unsigned char,unsigned char) -> bool {return false;}, - EffectProcess postFxHandler=[](int,unsigned char,unsigned char) -> bool {return false;}): + const EffectHandlerMap fxHandlers_={}, + const EffectHandlerMap postFxHandlers_={}): name(sysName), nameJ(sysNameJ), description(desc), @@ -233,8 +256,8 @@ struct DivSysDef { isSTD(isSTDChip), isCompound(compound), vgmVersion(vgmVer), - effectFunc(fxHandler), - postEffectFunc(postFxHandler) { + effectHandlers(fxHandlers_), + postEffectHandlers(postFxHandlers_) { memset(chanNames,0,DIV_MAX_CHANS*sizeof(void*)); memset(chanShortNames,0,DIV_MAX_CHANS*sizeof(void*)); memset(chanTypes,0,DIV_MAX_CHANS*sizeof(int)); diff --git a/src/engine/platform/abstract.cpp b/src/engine/platform/abstract.cpp index 5b732e7e9..358e54aa0 100644 --- a/src/engine/platform/abstract.cpp +++ b/src/engine/platform/abstract.cpp @@ -94,10 +94,6 @@ bool DivDispatch::getWantPreNote() { return false; } -const char* DivDispatch::getEffectName(unsigned char effect) { - return NULL; -} - void DivDispatch::setFlags(unsigned int flags) { } diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index 1b0075307..57c0e3e21 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -64,21 +64,6 @@ const char** DivPlatformAmiga::getRegisterSheet() { return regCheatSheetAmiga; } -const char* DivPlatformAmiga::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Toggle filter (0 disables; 1 enables)"; - break; - case 0x11: - return "11xx: Toggle AM with next channel"; - break; - case 0x12: - return "12xx: Toggle period modulation with next channel"; - break; - } - return NULL; -} - #define writeAudDat(x) \ chan[i].audDat=x; \ if (i<3 && chan[i].useV) { \ diff --git a/src/engine/platform/amiga.h b/src/engine/platform/amiga.h index e7372e63b..59617ec36 100644 --- a/src/engine/platform/amiga.h +++ b/src/engine/platform/amiga.h @@ -105,7 +105,6 @@ class DivPlatformAmiga: public DivDispatch { void notifyWaveChange(int wave); void notifyInsDeletion(void* ins); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); }; diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index 41042cd5c..1f51dc9bd 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -50,111 +50,6 @@ const char** DivPlatformArcade::getRegisterSheet() { return regCheatSheetOPM; } -const char* DivPlatformArcade::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Set noise frequency (xx: value; 0 disables noise)"; - break; - case 0x11: - return "11xx: Set feedback (0 to 7)"; - break; - case 0x12: - return "12xx: Set level of operator 1 (0 highest, 7F lowest)"; - break; - case 0x13: - return "13xx: Set level of operator 2 (0 highest, 7F lowest)"; - break; - case 0x14: - return "14xx: Set level of operator 3 (0 highest, 7F lowest)"; - break; - case 0x15: - return "15xx: Set level of operator 4 (0 highest, 7F lowest)"; - break; - case 0x16: - return "16xy: Set operator multiplier (x: operator from 1 to 4; y: multiplier)"; - break; - case 0x17: - return "17xx: Set LFO speed"; - break; - case 0x18: - return "18xx: Set LFO waveform (0 saw, 1 square, 2 triangle, 3 noise)"; - break; - case 0x19: - return "19xx: Set attack of all operators (0 to 1F)"; - break; - case 0x1a: - return "1Axx: Set attack of operator 1 (0 to 1F)"; - break; - case 0x1b: - return "1Bxx: Set attack of operator 2 (0 to 1F)"; - break; - case 0x1c: - return "1Cxx: Set attack of operator 3 (0 to 1F)"; - break; - case 0x1d: - return "1Dxx: Set attack of operator 4 (0 to 1F)"; - break; - case 0x1e: - return "1Exx: Set AM depth (0 to 7F)"; - break; - case 0x1f: - return "1Fxx: Set PM depth (0 to 7F)"; - break; - case 0x30: - return "30xx: Toggle hard envelope reset on new notes"; - break; - case 0x50: - return "50xy: Set AM (x: operator from 1 to 4 (0 for all ops); y: AM)"; - break; - case 0x51: - return "51xy: Set sustain level (x: operator from 1 to 4 (0 for all ops); y: sustain)"; - break; - case 0x52: - return "52xy: Set release (x: operator from 1 to 4 (0 for all ops); y: release)"; - break; - case 0x53: - return "53xy: Set detune (x: operator from 1 to 4 (0 for all ops); y: detune where 3 is center)"; - break; - case 0x54: - return "54xy: Set envelope scale (x: operator from 1 to 4 (0 for all ops); y: scale from 0 to 3)"; - break; - case 0x55: - return "55xy: Set detune 2 (x: operator from 1 to 4 (0 for all ops); y: detune from 0 to 3)"; - break; - case 0x56: - return "56xx: Set decay of all operators (0 to 1F)"; - break; - case 0x57: - return "57xx: Set decay of operator 1 (0 to 1F)"; - break; - case 0x58: - return "58xx: Set decay of operator 2 (0 to 1F)"; - break; - case 0x59: - return "59xx: Set decay of operator 3 (0 to 1F)"; - break; - case 0x5a: - return "5Axx: Set decay of operator 4 (0 to 1F)"; - break; - case 0x5b: - return "5Bxx: Set decay 2 of all operators (0 to 1F)"; - break; - case 0x5c: - return "5Cxx: Set decay 2 of operator 1 (0 to 1F)"; - break; - case 0x5d: - return "5Dxx: Set decay 2 of operator 2 (0 to 1F)"; - break; - case 0x5e: - return "5Exx: Set decay 2 of operator 3 (0 to 1F)"; - break; - case 0x5f: - return "5Fxx: Set decay 2 of operator 4 (0 to 1F)"; - break; - } - return NULL; -} - void DivPlatformArcade::acquire_nuked(short* bufL, short* bufR, size_t start, size_t len) { static int o[2]; diff --git a/src/engine/platform/arcade.h b/src/engine/platform/arcade.h index daa883620..93aa490d0 100644 --- a/src/engine/platform/arcade.h +++ b/src/engine/platform/arcade.h @@ -115,7 +115,6 @@ class DivPlatformArcade: public DivPlatformOPM { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformArcade(); diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index 8df5bd4ce..1b24ac733 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -73,42 +73,6 @@ const char** DivPlatformAY8910::getRegisterSheet() { return intellivision?regCheatSheetAY8914:regCheatSheetAY; } -const char* DivPlatformAY8910::getEffectName(unsigned char effect) { - switch (effect) { - case 0x20: - return "20xx: Set channel mode (bit 0: square; bit 1: noise; bit 2: envelope)"; - break; - case 0x21: - return "21xx: Set noise frequency (0 to 1F)"; - break; - case 0x22: - return "22xy: Set envelope mode (x: shape, y: enable for this channel)"; - break; - case 0x23: - return "23xx: Set envelope period low byte"; - break; - case 0x24: - return "24xx: Set envelope period high byte"; - break; - case 0x25: - return "25xx: Envelope slide up"; - break; - case 0x26: - return "26xx: Envelope slide down"; - break; - case 0x29: - return "29xy: Set auto-envelope (x: numerator; y: denominator)"; - break; - case 0x2e: - return "2Exx: Write to I/O port A"; - break; - case 0x2f: - return "2Fxx: Write to I/O port B"; - break; - } - return NULL; -} - void DivPlatformAY8910::acquire(short* bufL, short* bufR, size_t start, size_t len) { if (ayBufLen& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); DivPlatformAY8910(bool useExtMode=false, unsigned int eclk=COLOR_NTSC, unsigned char ediv=8): diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 581ebb9e8..0fc9091f2 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -77,54 +77,6 @@ const char** DivPlatformAY8930::getRegisterSheet() { return regCheatSheetAY8930; } -const char* DivPlatformAY8930::getEffectName(unsigned char effect) { - switch (effect) { - case 0x12: - return "12xx: Set duty cycle (0 to 8)"; - break; - case 0x20: - return "20xx: Set channel mode (bit 0: square; bit 1: noise; bit 2: envelope)"; - break; - case 0x21: - return "21xx: Set noise frequency (0 to 1F)"; - break; - case 0x22: - return "22xy: Set envelope mode (x: shape, y: enable for this channel)"; - break; - case 0x23: - return "23xx: Set envelope period low byte"; - break; - case 0x24: - return "24xx: Set envelope period high byte"; - break; - case 0x25: - return "25xx: Envelope slide up"; - break; - case 0x26: - return "26xx: Envelope slide down"; - break; - case 0x27: - return "27xx: Set noise AND mask"; - break; - case 0x28: - return "28xx: Set noise OR mask"; - break; - case 0x29: - return "29xy: Set auto-envelope (x: numerator; y: denominator)"; - break; - case 0x2d: - return "2Dxx: NOT TO BE EMPLOYED BY THE COMPOSER"; - break; - case 0x2e: - return "2Exx: Write to I/O port A"; - break; - case 0x2f: - return "2Fxx: Write to I/O port B"; - break; - } - return NULL; -} - void DivPlatformAY8930::acquire(short* bufL, short* bufR, size_t start, size_t len) { if (ayBufLen& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); }; diff --git a/src/engine/platform/bubsyswsg.cpp b/src/engine/platform/bubsyswsg.cpp index 5fe4462f4..fd00ebeeb 100644 --- a/src/engine/platform/bubsyswsg.cpp +++ b/src/engine/platform/bubsyswsg.cpp @@ -39,15 +39,6 @@ const char** DivPlatformBubSysWSG::getRegisterSheet() { return regCheatSheetBubSysWSG; } -const char* DivPlatformBubSysWSG::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Change waveform"; - break; - } - return NULL; -} - void DivPlatformBubSysWSG::acquire(short* bufL, short* bufR, size_t start, size_t len) { int chanOut=0; for (size_t h=start; h& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformBubSysWSG(); diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 9049ffec4..dc0cd8a2d 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -62,52 +62,6 @@ const char** DivPlatformC64::getRegisterSheet() { return regCheatSheetSID; } -const char* DivPlatformC64::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Set waveform (bit 0: triangle; bit 1: saw; bit 2: pulse; bit 3: noise)"; - break; - case 0x11: - return "11xx: Set coarse cutoff (not recommended; use 4xxx instead)"; - break; - case 0x12: - return "12xx: Set coarse pulse width (not recommended; use 3xxx instead)"; - break; - case 0x13: - return "13xx: Set resonance (0 to F)"; - break; - case 0x14: - return "14xx: Set filter mode (bit 0: low pass; bit 1: band pass; bit 2: high pass)"; - break; - case 0x15: - return "15xx: Set envelope reset time"; - break; - case 0x1a: - return "1Axx: Disable envelope reset for this channel (1 disables; 0 enables)"; - break; - case 0x1b: - return "1Bxy: Reset cutoff (x: on new note; y: now)"; - break; - case 0x1c: - return "1Cxy: Reset pulse width (x: on new note; y: now)"; - break; - case 0x1e: - return "1Exy: Change additional parameters"; - break; - case 0x30: case 0x31: case 0x32: case 0x33: - case 0x34: case 0x35: case 0x36: case 0x37: - case 0x38: case 0x39: case 0x3a: case 0x3b: - case 0x3c: case 0x3d: case 0x3e: case 0x3f: - return "3xxx: Set pulse width (0 to FFF)"; - break; - case 0x40: case 0x41: case 0x42: case 0x43: - case 0x44: case 0x45: case 0x46: case 0x47: - return "4xxx: Set cutoff (0 to 7FF)"; - break; - } - return NULL; -} - void DivPlatformC64::acquire(short* bufL, short* bufR, size_t start, size_t len) { int dcOff=sid.get_dc(0); for (size_t i=start; i& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void setChipModel(bool is6581); void quit(); diff --git a/src/engine/platform/fds.cpp b/src/engine/platform/fds.cpp index f9fc5b50b..fc4d3e775 100644 --- a/src/engine/platform/fds.cpp +++ b/src/engine/platform/fds.cpp @@ -55,30 +55,6 @@ const char** DivPlatformFDS::getRegisterSheet() { return regCheatSheetFDS; } -const char* DivPlatformFDS::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Change waveform"; - break; - case 0x11: - return "11xx: Set modulation depth"; - break; - case 0x12: - return "12xy: Set modulation speed high byte (x: enable; y: value)"; - break; - case 0x13: - return "13xx: Set modulation speed low byte"; - break; - case 0x14: - return "14xx: Set modulator position"; - break; - case 0x15: - return "15xx: Set modulator table to waveform"; - break; - } - return NULL; -} - void DivPlatformFDS::acquire_puNES(short* bufL, short* bufR, size_t start, size_t len) { for (size_t i=start; i& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformFDS(); diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index c29329b95..ab603266c 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -61,27 +61,6 @@ const char** DivPlatformGB::getRegisterSheet() { return regCheatSheetGB; } -const char* DivPlatformGB::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Change waveform"; - break; - case 0x11: - return "11xx: Set noise length (0: long; 1: short)"; - break; - case 0x12: - return "12xx: Set duty cycle (0 to 3)"; - break; - case 0x13: - return "13xy: Setup sweep (x: time; y: shift)"; - break; - case 0x14: - return "14xx: Set sweep direction (0: up; 1: down)"; - break; - } - return NULL; -} - void DivPlatformGB::acquire(short* bufL, short* bufR, size_t start, size_t len) { for (size_t i=start; i& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); void setFlags(unsigned int flags); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index b6dbb8d12..0260ea06c 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -27,108 +27,6 @@ #define IS_REALLY_MUTED(x) (isMuted[x] && (x<5 || !softPCM || (isMuted[5] && isMuted[6]))) -const char* DivPlatformGenesis::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xy: Setup LFO (x: enable; y: speed)"; - break; - case 0x11: - return "11xx: Set feedback (0 to 7)"; - break; - case 0x12: - return "12xx: Set level of operator 1 (0 highest, 7F lowest)"; - break; - case 0x13: - return "13xx: Set level of operator 2 (0 highest, 7F lowest)"; - break; - case 0x14: - return "14xx: Set level of operator 3 (0 highest, 7F lowest)"; - break; - case 0x15: - return "15xx: Set level of operator 4 (0 highest, 7F lowest)"; - break; - case 0x16: - return "16xy: Set operator multiplier (x: operator from 1 to 4; y: multiplier)"; - break; - case 0x17: - return "17xx: Enable channel 6 DAC"; - break; - case 0x18: - return "18xx: Toggle extended channel 3 mode"; - break; - case 0x19: - return "19xx: Set attack of all operators (0 to 1F)"; - break; - case 0x1a: - return "1Axx: Set attack of operator 1 (0 to 1F)"; - break; - case 0x1b: - return "1Bxx: Set attack of operator 2 (0 to 1F)"; - break; - case 0x1c: - return "1Cxx: Set attack of operator 3 (0 to 1F)"; - break; - case 0x1d: - return "1Dxx: Set attack of operator 4 (0 to 1F)"; - break; - case 0x30: - return "30xx: Toggle hard envelope reset on new notes"; - break; - case 0x50: - return "50xy: Set AM (x: operator from 1 to 4 (0 for all ops); y: AM)"; - break; - case 0x51: - return "51xy: Set sustain level (x: operator from 1 to 4 (0 for all ops); y: sustain)"; - break; - case 0x52: - return "52xy: Set release (x: operator from 1 to 4 (0 for all ops); y: release)"; - break; - case 0x53: - return "53xy: Set detune (x: operator from 1 to 4 (0 for all ops); y: detune where 3 is center)"; - break; - case 0x54: - return "54xy: Set envelope scale (x: operator from 1 to 4 (0 for all ops); y: scale from 0 to 3)"; - break; - case 0x55: - return "55xy: Set SSG envelope (x: operator from 1 to 4 (0 for all ops); y: 0-7 on, 8 off)"; - break; - case 0x56: - return "56xx: Set decay of all operators (0 to 1F)"; - break; - case 0x57: - return "57xx: Set decay of operator 1 (0 to 1F)"; - break; - case 0x58: - return "58xx: Set decay of operator 2 (0 to 1F)"; - break; - case 0x59: - return "59xx: Set decay of operator 3 (0 to 1F)"; - break; - case 0x5a: - return "5Axx: Set decay of operator 4 (0 to 1F)"; - break; - case 0x5b: - return "5Bxx: Set decay 2 of all operators (0 to 1F)"; - break; - case 0x5c: - return "5Cxx: Set decay 2 of operator 1 (0 to 1F)"; - break; - case 0x5d: - return "5Dxx: Set decay 2 of operator 2 (0 to 1F)"; - break; - case 0x5e: - return "5Exx: Set decay 2 of operator 3 (0 to 1F)"; - break; - case 0x5f: - return "5Fxx: Set decay 2 of operator 4 (0 to 1F)"; - break; - case 0xdf: - return "DFxx: Set sample playback direction (0: normal; 1: reverse)"; - break; - } - return NULL; -} - void DivPlatformGenesis::processDAC() { if (softPCM) { softPCMTimer+=chipClock/576; diff --git a/src/engine/platform/genesis.h b/src/engine/platform/genesis.h index c46a992d3..5e61fe678 100644 --- a/src/engine/platform/genesis.h +++ b/src/engine/platform/genesis.h @@ -144,7 +144,6 @@ class DivPlatformGenesis: public DivPlatformOPN { int getPortaFloor(int ch); void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); DivPlatformGenesis(): diff --git a/src/engine/platform/lynx.cpp b/src/engine/platform/lynx.cpp index 7c349e5a5..ead20590a 100644 --- a/src/engine/platform/lynx.cpp +++ b/src/engine/platform/lynx.cpp @@ -129,19 +129,6 @@ const char** DivPlatformLynx::getRegisterSheet() { return regCheatSheetLynx; } -const char* DivPlatformLynx::getEffectName(unsigned char effect) { - switch (effect) - { - case 0x30: case 0x31: case 0x32: case 0x33: - case 0x34: case 0x35: case 0x36: case 0x37: - case 0x38: case 0x39: case 0x3a: case 0x3b: - case 0x3c: case 0x3d: case 0x3e: case 0x3f: - return "3xxx: Load LFSR (0 to FFF)"; - break; - } - return NULL; -} - void DivPlatformLynx::acquire(short* bufL, short* bufR, size_t start, size_t len) { for (size_t h=start; h& wlist); const char** getRegisterSheet(); - const char* getEffectName( unsigned char effect ); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformLynx(); diff --git a/src/engine/platform/mmc5.cpp b/src/engine/platform/mmc5.cpp index 2154e855f..b5bb5a9e8 100644 --- a/src/engine/platform/mmc5.cpp +++ b/src/engine/platform/mmc5.cpp @@ -43,15 +43,6 @@ const char** DivPlatformMMC5::getRegisterSheet() { return regCheatSheetMMC5; } -const char* DivPlatformMMC5::getEffectName(unsigned char effect) { - switch (effect) { - case 0x12: - return "12xx: Set duty cycle/noise mode (pulse: 0 to 3; noise: 0 or 1)"; - break; - } - return NULL; -} - void DivPlatformMMC5::acquire(short* bufL, short* bufR, size_t start, size_t len) { for (size_t i=start; i& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformMMC5(); diff --git a/src/engine/platform/msm6258.cpp b/src/engine/platform/msm6258.cpp index dc81950ef..0ba3ae0b8 100644 --- a/src/engine/platform/msm6258.cpp +++ b/src/engine/platform/msm6258.cpp @@ -30,18 +30,6 @@ const char** DivPlatformMSM6258::getRegisterSheet() { return NULL; } -const char* DivPlatformMSM6258::getEffectName(unsigned char effect) { - switch (effect) { - case 0x20: - return "20xx: Set frequency divider (0-2)"; - break; - case 0x21: - return "21xx: Select clock rate (0: full; 1: half)"; - break; - } - return NULL; -} - void DivPlatformMSM6258::acquire(short* bufL, short* bufR, size_t start, size_t len) { short* outs[2]={ &msmOut, diff --git a/src/engine/platform/msm6258.h b/src/engine/platform/msm6258.h index cd975c8f8..f6a351b5e 100644 --- a/src/engine/platform/msm6258.h +++ b/src/engine/platform/msm6258.h @@ -109,7 +109,6 @@ class DivPlatformMSM6258: public DivDispatch { void poke(std::vector& wlist); void setFlags(unsigned int flags); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); const void* getSampleMem(int index); size_t getSampleMemCapacity(int index); size_t getSampleMemUsage(int index); diff --git a/src/engine/platform/msm6295.cpp b/src/engine/platform/msm6295.cpp index fc5f9ea30..0a76a2c9b 100644 --- a/src/engine/platform/msm6295.cpp +++ b/src/engine/platform/msm6295.cpp @@ -30,15 +30,6 @@ const char** DivPlatformMSM6295::getRegisterSheet() { return NULL; } -const char* DivPlatformMSM6295::getEffectName(unsigned char effect) { - switch (effect) { - case 0x20: - return "20xx: Set chip output rate (0: clock/132; 1: clock/165)"; - break; - } - return NULL; -} - u8 DivPlatformMSM6295::read_byte(u32 address) { if (adpcmMem==NULL || address>=getSampleMemCapacity(0)) { return 0; diff --git a/src/engine/platform/msm6295.h b/src/engine/platform/msm6295.h index f01c1b233..0953bd33e 100644 --- a/src/engine/platform/msm6295.h +++ b/src/engine/platform/msm6295.h @@ -97,7 +97,6 @@ class DivPlatformMSM6295: public DivDispatch, public vgsound_emu_mem_intf { virtual void poke(std::vector& wlist) override; virtual void setFlags(unsigned int flags) override; virtual const char** getRegisterSheet() override; - virtual const char* getEffectName(unsigned char effect) override; virtual const void* getSampleMem(int index) override; virtual size_t getSampleMemCapacity(int index) override; virtual size_t getSampleMemUsage(int index) override; diff --git a/src/engine/platform/n163.cpp b/src/engine/platform/n163.cpp index b20b460e0..52352dc62 100644 --- a/src/engine/platform/n163.cpp +++ b/src/engine/platform/n163.cpp @@ -108,51 +108,6 @@ const char** DivPlatformN163::getRegisterSheet() { return regCheatSheetN163; } -const char* DivPlatformN163::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Select waveform"; - break; - case 0x11: - return "11xx: Set waveform position in RAM (single nibble unit)"; - break; - case 0x12: - return "12xx: Set waveform length in RAM (04 to FC, 4 nibble unit)"; - break; - case 0x13: - return "130x: Change waveform update mode (0: off, bit 0: update now, bit 1: update when every waveform changes)"; - break; - case 0x14: - return "14xx: Select waveform for load to RAM"; - break; - case 0x15: - return "15xx: Set waveform position for load to RAM (single nibble unit)"; - break; - case 0x16: - return "16xx: Set waveform length for load to RAM (04 to FC, 4 nibble unit)"; - break; - case 0x17: - return "170x: Change waveform load mode (0: off, bit 0: load now, bit 1: load when every waveform changes)"; - break; - case 0x18: - return "180x: Change channel limits (0 to 7, x + 1)"; - break; - case 0x20: - return "20xx: (Global) Select waveform for load to RAM"; - break; - case 0x21: - return "21xx: (Global) Set waveform position for load to RAM (single nibble unit)"; - break; - case 0x22: - return "22xx: (Global) Set waveform length for load to RAM (04 to FC, 4 nibble unit)"; - break; - case 0x23: - return "230x: (Global) Change waveform load mode (0: off, bit 0: load now, bit 1: load when every waveform changes)"; - break; - } - return NULL; -} - void DivPlatformN163::acquire(short* bufL, short* bufR, size_t start, size_t len) { for (size_t i=start; i& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformN163(); diff --git a/src/engine/platform/namcowsg.cpp b/src/engine/platform/namcowsg.cpp index 00b127930..e88bb0ebf 100644 --- a/src/engine/platform/namcowsg.cpp +++ b/src/engine/platform/namcowsg.cpp @@ -151,18 +151,6 @@ const char** DivPlatformNamcoWSG::getRegisterSheet() { return regCheatSheetNamcoWSG; } -const char* DivPlatformNamcoWSG::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Change waveform"; - break; - case 0x11: - return "11xx: Toggle noise mode"; - break; - } - return NULL; -} - void DivPlatformNamcoWSG::acquire(short* bufL, short* bufR, size_t start, size_t len) { while (!writes.empty()) { QueuedWrite w=writes.front(); diff --git a/src/engine/platform/namcowsg.h b/src/engine/platform/namcowsg.h index 4ab81bdce..ede25e8e6 100644 --- a/src/engine/platform/namcowsg.h +++ b/src/engine/platform/namcowsg.h @@ -96,7 +96,6 @@ class DivPlatformNamcoWSG: public DivDispatch { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformNamcoWSG(); diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index bd1be94a8..a55199d15 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -62,27 +62,6 @@ const char** DivPlatformNES::getRegisterSheet() { return regCheatSheetNES; } -const char* DivPlatformNES::getEffectName(unsigned char effect) { - switch (effect) { - case 0x11: - return "11xx: Write to delta modulation counter (0 to 7F)"; - break; - case 0x12: - return "12xx: Set duty cycle/noise mode (pulse: 0 to 3; noise: 0 or 1)"; - break; - case 0x13: - return "13xy: Sweep up (x: time; y: shift)"; - break; - case 0x14: - return "14xy: Sweep down (x: time; y: shift)"; - break; - case 0x18: - return "18xx: Select PCM/DPCM mode (0: PCM; 1: DPCM)"; - break; - } - return NULL; -} - void DivPlatformNES::doWrite(unsigned short addr, unsigned char data) { if (useNP) { nes1_NP->Write(addr,data); diff --git a/src/engine/platform/nes.h b/src/engine/platform/nes.h index 35c51df74..c00003305 100644 --- a/src/engine/platform/nes.h +++ b/src/engine/platform/nes.h @@ -106,7 +106,6 @@ class DivPlatformNES: public DivDispatch { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); const void* getSampleMem(int index); size_t getSampleMemCapacity(int index); size_t getSampleMemUsage(int index); diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 8b76db213..784bd08fa 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -152,98 +152,6 @@ const int orderedOpsL[4]={ #define ADDR_FREQH 0xb0 #define ADDR_LR_FB_ALG 0xc0 -const char* DivPlatformOPL::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Set global AM depth (0: 1dB, 1: 4.8dB)"; - break; - case 0x11: - return "11xx: Set feedback (0 to 7)"; - break; - case 0x12: - return "12xx: Set level of operator 1 (0 highest, 3F lowest)"; - break; - case 0x13: - return "13xx: Set level of operator 2 (0 highest, 3F lowest)"; - break; - case 0x14: - return "14xx: Set level of operator 3 (0 highest, 3F lowest; 4-op only)"; - break; - case 0x15: - return "15xx: Set level of operator 4 (0 highest, 3F lowest; 4-op only)"; - break; - case 0x16: - return "16xy: Set operator multiplier (x: operator from 1 to 4; y: multiplier)"; - break; - case 0x17: - return "17xx: Set global vibrato depth (0: normal, 1: double)"; - break; - case 0x18: - if (properDrumsSys) { - return "18xx: Toggle drums mode (1: enabled; 0: disabled)"; - } - break; - case 0x19: - return "19xx: Set attack of all operators (0 to F)"; - break; - case 0x1a: - return "1Axx: Set attack of operator 1 (0 to F)"; - break; - case 0x1b: - return "1Bxx: Set attack of operator 2 (0 to F)"; - break; - case 0x1c: - return "1Cxx: Set attack of operator 3 (0 to F; 4-op only)"; - break; - case 0x1d: - return "1Dxx: Set attack of operator 4 (0 to F; 4-op only)"; - break; - case 0x2a: - return "2Axy: Set waveform (x: operator from 1 to 4 (0 for all ops); y: waveform from 0 to 3 in OPL2 and 0 to 7 in OPL3)"; - break; - case 0x30: - return "30xx: Toggle hard envelope reset on new notes"; - break; - case 0x50: - return "50xy: Set AM (x: operator from 1 to 4 (0 for all ops); y: AM)"; - break; - case 0x51: - return "51xy: Set sustain level (x: operator from 1 to 4 (0 for all ops); y: sustain)"; - break; - case 0x52: - return "52xy: Set release (x: operator from 1 to 4 (0 for all ops); y: release)"; - break; - case 0x53: - return "53xy: Set vibrato (x: operator from 1 to 4 (0 for all ops); y: enabled)"; - break; - case 0x54: - return "54xy: Set key scale level (x: operator from 1 to 4 (0 for all ops); y: level from 0 to 3)"; - break; - case 0x55: - return "55xy: Set envelope sustain (x: operator from 1 to 4 (0 for all ops); y: enabled)"; - break; - case 0x56: - return "56xx: Set decay of all operators (0 to F)"; - break; - case 0x57: - return "57xx: Set decay of operator 1 (0 to F)"; - break; - case 0x58: - return "58xx: Set decay of operator 2 (0 to F)"; - break; - case 0x59: - return "59xx: Set decay of operator 3 (0 to F; 4-op only)"; - break; - case 0x5a: - return "5Axx: Set decay of operator 4 (0 to F; 4-op only)"; - break; - case 0x5b: - return "5Bxy: Set whether key will scale envelope (x: operator from 1 to 4 (0 for all ops); y: enabled)"; - break; - } - return NULL; -} - void DivPlatformOPL::acquire_nuked(short* bufL, short* bufR, size_t start, size_t len) { static short o[2]; static int os[2]; diff --git a/src/engine/platform/opl.h b/src/engine/platform/opl.h index 3d6497367..e3b16679f 100644 --- a/src/engine/platform/opl.h +++ b/src/engine/platform/opl.h @@ -145,7 +145,6 @@ class DivPlatformOPL: public DivDispatch { int getPortaFloor(int ch); void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); - const char* getEffectName(unsigned char effect); const void* getSampleMem(int index); size_t getSampleMemCapacity(int index); size_t getSampleMemUsage(int index); diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index 5c9611b43..e29f6e622 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -27,68 +27,6 @@ #define CHIP_FREQBASE 1180068 -const char* DivPlatformOPLL::getEffectName(unsigned char effect) { - switch (effect) { - case 0x11: - return "11xx: Set feedback (0 to 7)"; - break; - case 0x12: - return "12xx: Set level of operator 1 (0 highest, 3F lowest)"; - break; - case 0x13: - return "13xx: Set level of operator 2 (0 highest, F lowest)"; - break; - case 0x16: - return "16xy: Set operator multiplier (x: operator from 1 to 2; y: multiplier)"; - break; - case 0x18: - if (properDrumsSys) { - return "18xx: Toggle drums mode (1: enabled; 0: disabled)"; - } - break; - case 0x19: - return "19xx: Set attack of all operators (0 to F)"; - break; - case 0x1a: - return "1Axx: Set attack of operator 1 (0 to F)"; - break; - case 0x1b: - return "1Bxx: Set attack of operator 2 (0 to F)"; - break; - case 0x50: - return "50xy: Set AM (x: operator from 1 to 2 (0 for all ops); y: AM)"; - break; - case 0x51: - return "51xy: Set sustain level (x: operator from 1 to 2 (0 for all ops); y: sustain)"; - break; - case 0x52: - return "52xy: Set release (x: operator from 1 to 2 (0 for all ops); y: release)"; - break; - case 0x53: - return "53xy: Set vibrato (x: operator from 1 to 2 (0 for all ops); y: enabled)"; - break; - case 0x54: - return "54xy: Set key scale level (x: operator from 1 to 2 (0 for all ops); y: level from 0 to 3)"; - break; - case 0x55: - return "55xy: Set envelope sustain (x: operator from 1 to 2 (0 for all ops); y: enabled)"; - break; - case 0x56: - return "56xx: Set decay of all operators (0 to F)"; - break; - case 0x57: - return "57xx: Set decay of operator 1 (0 to F)"; - break; - case 0x58: - return "58xx: Set decay of operator 2 (0 to F)"; - break; - case 0x5b: - return "5Bxy: Set whether key will scale envelope (x: operator from 1 to 2 (0 for all ops); y: enabled)"; - break; - } - return NULL; -} - const unsigned char cycleMapOPLL[18]={ 8, 7, 6, 7, 8, 7, 8, 6, 0, 1, 2, 7, 8, 9, 3, 4, 5, 9 }; diff --git a/src/engine/platform/opll.h b/src/engine/platform/opll.h index dad660dea..21a77b4e6 100644 --- a/src/engine/platform/opll.h +++ b/src/engine/platform/opll.h @@ -122,7 +122,6 @@ class DivPlatformOPLL: public DivDispatch { int getPortaFloor(int ch); void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformOPLL(); diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index 3fc7a05bd..1dcf24511 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -53,27 +53,6 @@ const char** DivPlatformPCE::getRegisterSheet() { return regCheatSheetPCE; } -const char* DivPlatformPCE::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Change waveform"; - break; - case 0x11: - return "11xx: Toggle noise mode"; - break; - case 0x12: - return "12xx: Setup LFO (0: disabled; 1: 1x depth; 2: 16x depth; 3: 256x depth)"; - break; - case 0x13: - return "13xx: Set LFO speed"; - break; - case 0x17: - return "17xx: Toggle PCM mode"; - break; - } - return NULL; -} - void DivPlatformPCE::acquire(short* bufL, short* bufR, size_t start, size_t len) { for (size_t h=start; h& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformPCE(); diff --git a/src/engine/platform/pcspkr.cpp b/src/engine/platform/pcspkr.cpp index d40a297ae..260f5bbd6 100644 --- a/src/engine/platform/pcspkr.cpp +++ b/src/engine/platform/pcspkr.cpp @@ -190,10 +190,6 @@ const char** DivPlatformPCSpeaker::getRegisterSheet() { return regCheatSheetPCSpeaker; } -const char* DivPlatformPCSpeaker::getEffectName(unsigned char effect) { - return NULL; -} - const float cut=0.05; const float reso=0.06; diff --git a/src/engine/platform/pcspkr.h b/src/engine/platform/pcspkr.h index cb6f070fe..ba6275c32 100644 --- a/src/engine/platform/pcspkr.h +++ b/src/engine/platform/pcspkr.h @@ -113,7 +113,6 @@ class DivPlatformPCSpeaker: public DivDispatch { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformPCSpeaker(); diff --git a/src/engine/platform/pet.cpp b/src/engine/platform/pet.cpp index dc524e45f..4e1c39a97 100644 --- a/src/engine/platform/pet.cpp +++ b/src/engine/platform/pet.cpp @@ -37,15 +37,6 @@ const char** DivPlatformPET::getRegisterSheet() { return regCheatSheet6522; } -const char* DivPlatformPET::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Change waveform"; - break; - } - return NULL; -} - // high-level emulation of 6522 shift register and driver software for now void DivPlatformPET::rWrite(unsigned int addr, unsigned char val) { bool hwSROutput=((regPool[11]>>2)&7)==4; diff --git a/src/engine/platform/pet.h b/src/engine/platform/pet.h index 06c7e736a..8de217790 100644 --- a/src/engine/platform/pet.h +++ b/src/engine/platform/pet.h @@ -80,7 +80,6 @@ class DivPlatformPET: public DivDispatch { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformPET(); diff --git a/src/engine/platform/qsound.cpp b/src/engine/platform/qsound.cpp index ca6a794cd..863c0e1fd 100644 --- a/src/engine/platform/qsound.cpp +++ b/src/engine/platform/qsound.cpp @@ -249,24 +249,6 @@ const char** DivPlatformQSound::getRegisterSheet() { return regCheatSheetQSound; } -const char* DivPlatformQSound::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Set echo feedback level (00 to FF)"; - break; - case 0x11: - return "11xx: Set channel echo level (00 to FF)"; - break; - case 0x12: - return "12xx: Toggle QSound algorithm (0: disabled; 1: enabled)"; - break; - default: - if ((effect & 0xf0) == 0x30) { - return "3xxx: Set echo delay buffer length (000 to AA5)"; - } - } - return NULL; -} void DivPlatformQSound::acquire(short* bufL, short* bufR, size_t start, size_t len) { for (size_t h=start; h& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); const void* getSampleMem(int index = 0); size_t getSampleMemCapacity(int index = 0); size_t getSampleMemUsage(int index = 0); diff --git a/src/engine/platform/rf5c68.cpp b/src/engine/platform/rf5c68.cpp index e4a39d44e..e19b945b0 100644 --- a/src/engine/platform/rf5c68.cpp +++ b/src/engine/platform/rf5c68.cpp @@ -43,10 +43,6 @@ const char** DivPlatformRF5C68::getRegisterSheet() { return regCheatSheetRF5C68; } -const char* DivPlatformRF5C68::getEffectName(unsigned char effect) { - return NULL; -} - void DivPlatformRF5C68::chWrite(unsigned char ch, unsigned int addr, unsigned char val) { if (!skipRegisterWrites) { if (curChan!=ch) { diff --git a/src/engine/platform/rf5c68.h b/src/engine/platform/rf5c68.h index 6946b4900..d82c926e6 100644 --- a/src/engine/platform/rf5c68.h +++ b/src/engine/platform/rf5c68.h @@ -92,7 +92,6 @@ class DivPlatformRF5C68: public DivDispatch { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); const void* getSampleMem(int index = 0); size_t getSampleMemCapacity(int index = 0); size_t getSampleMemUsage(int index = 0); diff --git a/src/engine/platform/saa.cpp b/src/engine/platform/saa.cpp index 103c3348f..a05a61d4f 100644 --- a/src/engine/platform/saa.cpp +++ b/src/engine/platform/saa.cpp @@ -56,21 +56,6 @@ const char** DivPlatformSAA1099::getRegisterSheet() { return regCheatSheetSAA; } -const char* DivPlatformSAA1099::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xy: Set channel mode (x: noise; y: tone)"; - break; - case 0x11: - return "11xx: Set noise frequency"; - break; - case 0x12: - return "12xx: Setup envelope (refer to docs for more information)"; - break; - } - return NULL; -} - void DivPlatformSAA1099::acquire_saaSound(short* bufL, short* bufR, size_t start, size_t len) { if (saaBufLen& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); }; diff --git a/src/engine/platform/scc.cpp b/src/engine/platform/scc.cpp index 485839bf1..a72257629 100644 --- a/src/engine/platform/scc.cpp +++ b/src/engine/platform/scc.cpp @@ -80,15 +80,6 @@ const char** DivPlatformSCC::getRegisterSheet() { return isPlus ? regCheatSheetSCCPlus : regCheatSheetSCC; } -const char* DivPlatformSCC::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Change waveform"; - break; - } - return NULL; -} - void DivPlatformSCC::acquire(short* bufL, short* bufR, size_t start, size_t len) { for (size_t h=start; h& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); void setFlags(unsigned int flags); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void setChipModel(bool isPlus); diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index d66fcce0b..e406e293b 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -26,15 +26,6 @@ //#define rWrite(a,v) if (!skipRegisterWrites) {pendingWrites[a]=v;} //#define immWrite(a,v) if (!skipRegisterWrites) {writes.emplace(a,v); if (dumpWrites) {addWrite(a,v);} } -const char* DivPlatformSegaPCM::getEffectName(unsigned char effect) { - switch (effect) { - case 0x20: - return "20xx: Set PCM frequency"; - break; - } - return NULL; -} - void DivPlatformSegaPCM::acquire(short* bufL, short* bufR, size_t start, size_t len) { static int os[2]; diff --git a/src/engine/platform/segapcm.h b/src/engine/platform/segapcm.h index 6edc85302..0dd4b837a 100644 --- a/src/engine/platform/segapcm.h +++ b/src/engine/platform/segapcm.h @@ -114,7 +114,6 @@ class DivPlatformSegaPCM: public DivDispatch { bool isStereo(); void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformSegaPCM(); diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 3d11a5ac9..2988be2f8 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -38,15 +38,6 @@ const char** DivPlatformSMS::getRegisterSheet() { return stereo?regCheatSheetGG:regCheatSheetSN; } -const char* DivPlatformSMS::getEffectName(unsigned char effect) { - switch (effect) { - case 0x20: - return "20xy: Set noise mode (x: preset freq/ch3 freq; y: thin pulse/noise)"; - break; - } - return NULL; -} - void DivPlatformSMS::acquire_nuked(short* bufL, short* bufR, size_t start, size_t len) { int oL=0; int oR=0; diff --git a/src/engine/platform/sms.h b/src/engine/platform/sms.h index 35bb44bab..eef54da1e 100644 --- a/src/engine/platform/sms.h +++ b/src/engine/platform/sms.h @@ -101,7 +101,6 @@ class DivPlatformSMS: public DivDispatch { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); void setNuked(bool value); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); diff --git a/src/engine/platform/su.cpp b/src/engine/platform/su.cpp index afcdba242..ca933650f 100644 --- a/src/engine/platform/su.cpp +++ b/src/engine/platform/su.cpp @@ -33,72 +33,6 @@ const char** DivPlatformSoundUnit::getRegisterSheet() { return NULL; } -const char* DivPlatformSoundUnit::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Set waveform (0 to 7)"; - break; - case 0x12: - return "12xx: Set pulse width (0 to 7F)"; - break; - case 0x13: - return "13xx: Set resonance (0 to F)"; - break; - case 0x14: - return "14xx: Set filter mode (bit 0: ring mod; bit 1: low pass; bit 2: high pass; bit 3: band pass)"; - break; - case 0x15: - return "15xx: Set frequency sweep period low byte"; - break; - case 0x16: - return "16xx: Set frequency sweep period high byte"; - break; - case 0x17: - return "17xx: Set volume sweep period low byte"; - break; - case 0x18: - return "18xx: Set volume sweep period high byte"; - break; - case 0x19: - return "19xx: Set cutoff sweep period low byte"; - break; - case 0x1a: - return "1Axx: Set cutoff sweep period high byte"; - break; - case 0x1b: - return "1Bxx: Set frequency sweep boundary"; - break; - case 0x1c: - return "1Cxx: Set volume sweep boundary"; - break; - case 0x1d: - return "1Dxx: Set cutoff sweep boundary"; - break; - case 0x1e: - return "1Exx: Set phase reset period low byte"; - break; - case 0x1f: - return "1Fxx: Set phase reset period high byte"; - break; - case 0x20: - return "20xx: Toggle frequency sweep (bit 0-6: speed; bit 7: direction is up)"; - break; - case 0x21: - return "21xx: Toggle volume sweep (bit 0-4: speed; bit 5: direciton is up; bit 6: loop; bit 7: alternate)"; - break; - case 0x22: - return "22xx: Toggle cutoff sweep (bit 0-6: speed; bit 7: direction is up)"; - break; - case 0x40: case 0x41: case 0x42: case 0x43: - case 0x44: case 0x45: case 0x46: case 0x47: - case 0x48: case 0x49: case 0x4a: case 0x4b: - case 0x4c: case 0x4d: case 0x4e: case 0x4f: - return "4xxx: Set cutoff (0 to FFF)"; - break; - } - return NULL; -} - double DivPlatformSoundUnit::NOTE_SU(int ch, int note) { if (chan[ch].switchRoles) { return NOTE_PERIODIC(note); diff --git a/src/engine/platform/su.h b/src/engine/platform/su.h index 2392624f6..d76d07227 100644 --- a/src/engine/platform/su.h +++ b/src/engine/platform/su.h @@ -133,7 +133,6 @@ class DivPlatformSoundUnit: public DivDispatch { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); const void* getSampleMem(int index); size_t getSampleMemCapacity(int index); size_t getSampleMemUsage(int index); diff --git a/src/engine/platform/swan.cpp b/src/engine/platform/swan.cpp index b6da23271..cdab93d5c 100644 --- a/src/engine/platform/swan.cpp +++ b/src/engine/platform/swan.cpp @@ -50,27 +50,6 @@ const char** DivPlatformSwan::getRegisterSheet() { return regCheatSheetWS; } -const char* DivPlatformSwan::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Change waveform"; - break; - case 0x11: - return "11xx: Setup noise mode (0: disabled; 1-8: enabled/tap)"; - break; - case 0x12: - return "12xx: Setup sweep period (0: disabled; 1-20: enabled/period)"; - break; - case 0x13: - return "13xx: Set sweep amount"; - break; - case 0x17: - return "17xx: Toggle PCM mode"; - break; - } - return NULL; -} - void DivPlatformSwan::acquire(short* bufL, short* bufR, size_t start, size_t len) { for (size_t h=start; h& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformSwan(); diff --git a/src/engine/platform/tia.cpp b/src/engine/platform/tia.cpp index ddb380844..bebc1ff2e 100644 --- a/src/engine/platform/tia.cpp +++ b/src/engine/platform/tia.cpp @@ -34,15 +34,6 @@ const char* regCheatSheetTIA[]={ NULL }; -const char* DivPlatformTIA::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Select shape (0 to F)"; - break; - } - return NULL; -} - const char** DivPlatformTIA::getRegisterSheet() { return regCheatSheetTIA; } diff --git a/src/engine/platform/tia.h b/src/engine/platform/tia.h index cabe91533..168175367 100644 --- a/src/engine/platform/tia.h +++ b/src/engine/platform/tia.h @@ -67,7 +67,6 @@ class DivPlatformTIA: public DivDispatch { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); }; diff --git a/src/engine/platform/tx81z.cpp b/src/engine/platform/tx81z.cpp index 9d24e4db5..e6e38a128 100644 --- a/src/engine/platform/tx81z.cpp +++ b/src/engine/platform/tx81z.cpp @@ -55,139 +55,6 @@ const char** DivPlatformTX81Z::getRegisterSheet() { return regCheatSheetOPZ; } -const char* DivPlatformTX81Z::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Set noise frequency (xx: value; 0 disables noise)"; - break; - case 0x11: - return "11xx: Set feedback (0 to 7)"; - break; - case 0x12: - return "12xx: Set level of operator 1 (0 highest, 7F lowest)"; - break; - case 0x13: - return "13xx: Set level of operator 2 (0 highest, 7F lowest)"; - break; - case 0x14: - return "14xx: Set level of operator 3 (0 highest, 7F lowest)"; - break; - case 0x15: - return "15xx: Set level of operator 4 (0 highest, 7F lowest)"; - break; - case 0x16: - return "16xy: Set operator multiplier (x: operator from 1 to 4; y: multiplier)"; - break; - case 0x17: - return "17xx: Set LFO speed"; - break; - case 0x18: - return "18xx: Set LFO waveform (0 saw, 1 square, 2 triangle, 3 noise)"; - break; - case 0x19: - return "19xx: Set attack of all operators (0 to 1F)"; - break; - case 0x1a: - return "1Axx: Set attack of operator 1 (0 to 1F)"; - break; - case 0x1b: - return "1Bxx: Set attack of operator 2 (0 to 1F)"; - break; - case 0x1c: - return "1Cxx: Set attack of operator 3 (0 to 1F)"; - break; - case 0x1d: - return "1Dxx: Set attack of operator 4 (0 to 1F)"; - break; - case 0x1e: - return "1Exx: Set AM depth (0 to 7F)"; - break; - case 0x1f: - return "1Fxx: Set PM depth (0 to 7F)"; - break; - case 0x28: - return "28xy: Set reverb (x: operator from 1 to 4 (0 for all ops); y: reverb from 0 to 7)"; - break; - case 0x2a: - return "2Axy: Set waveform (x: operator from 1 to 4 (0 for all ops); y: waveform from 0 to 7)"; - break; - case 0x2b: - return "2Bxy: Set envelope generator shift (x: operator from 1 to 4 (0 for all ops); y: shift from 0 to 3)"; - break; - case 0x2c: - return "2Cxy: Set fine multiplier (x: operator from 1 to 4 (0 for all ops); y: fine)"; - break; - case 0x2f: - return "2Fxx: Toggle hard envelope reset on new notes"; - break; - case 0x30: case 0x31: case 0x32: case 0x33: - case 0x34: case 0x35: case 0x36: case 0x37: - return "3xyy: Set fixed frequency of operator 1 (x: octave from 0 to 7; y: frequency)"; - break; - case 0x38: case 0x39: case 0x3a: case 0x3b: - case 0x3c: case 0x3d: case 0x3e: case 0x3f: - return "3xyy: Set fixed frequency of operator 2 (x: octave from 8 to F; y: frequency)"; - break; - case 0x40: case 0x41: case 0x42: case 0x43: - case 0x44: case 0x45: case 0x46: case 0x47: - return "4xyy: Set fixed frequency of operator 3 (x: octave from 0 to 7; y: frequency)"; - break; - case 0x48: case 0x49: case 0x4a: case 0x4b: - case 0x4c: case 0x4d: case 0x4e: case 0x4f: - return "4xyy: Set fixed frequency of operator 4 (x: octave from 8 to F; y: frequency)"; - break; - case 0x50: - return "50xy: Set AM (x: operator from 1 to 4 (0 for all ops); y: AM)"; - break; - case 0x51: - return "51xy: Set sustain level (x: operator from 1 to 4 (0 for all ops); y: sustain)"; - break; - case 0x52: - return "52xy: Set release (x: operator from 1 to 4 (0 for all ops); y: release)"; - break; - case 0x53: - return "53xy: Set detune (x: operator from 1 to 4 (0 for all ops); y: detune where 3 is center)"; - break; - case 0x54: - return "54xy: Set envelope scale (x: operator from 1 to 4 (0 for all ops); y: scale from 0 to 3)"; - break; - case 0x55: - return "55xy: Set detune 2 (x: operator from 1 to 4 (0 for all ops); y: detune from 0 to 3)"; - break; - case 0x56: - return "56xx: Set decay of all operators (0 to 1F)"; - break; - case 0x57: - return "57xx: Set decay of operator 1 (0 to 1F)"; - break; - case 0x58: - return "58xx: Set decay of operator 2 (0 to 1F)"; - break; - case 0x59: - return "59xx: Set decay of operator 3 (0 to 1F)"; - break; - case 0x5a: - return "5Axx: Set decay of operator 4 (0 to 1F)"; - break; - case 0x5b: - return "5Bxx: Set decay 2 of all operators (0 to 1F)"; - break; - case 0x5c: - return "5Cxx: Set decay 2 of operator 1 (0 to 1F)"; - break; - case 0x5d: - return "5Dxx: Set decay 2 of operator 2 (0 to 1F)"; - break; - case 0x5e: - return "5Exx: Set decay 2 of operator 3 (0 to 1F)"; - break; - case 0x5f: - return "5Fxx: Set decay 2 of operator 4 (0 to 1F)"; - break; - } - return NULL; -} - void DivPlatformTX81Z::acquire(short* bufL, short* bufR, size_t start, size_t len) { static int os[2]; diff --git a/src/engine/platform/tx81z.h b/src/engine/platform/tx81z.h index e867416cf..d1e427282 100644 --- a/src/engine/platform/tx81z.h +++ b/src/engine/platform/tx81z.h @@ -108,7 +108,6 @@ class DivPlatformTX81Z: public DivPlatformOPM { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformTX81Z(); diff --git a/src/engine/platform/vera.cpp b/src/engine/platform/vera.cpp index 6376cc19e..e50bcd6ea 100644 --- a/src/engine/platform/vera.cpp +++ b/src/engine/platform/vera.cpp @@ -51,18 +51,6 @@ const char** DivPlatformVERA::getRegisterSheet() { return regCheatSheetVERA; } -const char* DivPlatformVERA::getEffectName(unsigned char effect) { - switch (effect) { - case 0x20: - return "20xx: Change waveform"; - break; - case 0x22: - return "22xx: Set duty cycle (0 to 3F)"; - break; - } - return NULL; -} - void DivPlatformVERA::acquire(short* bufL, short* bufR, size_t start, size_t len) { // both PSG part and PCM part output a full 16-bit range, putting bufL/R // argument right into both could cause an overflow diff --git a/src/engine/platform/vera.h b/src/engine/platform/vera.h index 612b4354b..53e766dcd 100644 --- a/src/engine/platform/vera.h +++ b/src/engine/platform/vera.h @@ -79,7 +79,6 @@ class DivPlatformVERA: public DivDispatch { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformVERA(); diff --git a/src/engine/platform/vic20.cpp b/src/engine/platform/vic20.cpp index 771b87d1e..5c0bdf461 100644 --- a/src/engine/platform/vic20.cpp +++ b/src/engine/platform/vic20.cpp @@ -39,15 +39,6 @@ const char** DivPlatformVIC20::getRegisterSheet() { return regCheatSheetVIC; } -const char* DivPlatformVIC20::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Change waveform"; - break; - } - return NULL; -} - void DivPlatformVIC20::acquire(short* bufL, short* bufR, size_t start, size_t len) { const unsigned char loadFreq[3] = {0x7e, 0x7d, 0x7b}; const unsigned char wavePatterns[16] = { diff --git a/src/engine/platform/vic20.h b/src/engine/platform/vic20.h index d23f27be8..d4b56028c 100644 --- a/src/engine/platform/vic20.h +++ b/src/engine/platform/vic20.h @@ -82,7 +82,6 @@ class DivPlatformVIC20: public DivDispatch { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformVIC20(); diff --git a/src/engine/platform/vrc6.cpp b/src/engine/platform/vrc6.cpp index 8a34d9252..9a7bcef0d 100644 --- a/src/engine/platform/vrc6.cpp +++ b/src/engine/platform/vrc6.cpp @@ -46,18 +46,6 @@ const char** DivPlatformVRC6::getRegisterSheet() { return regCheatSheetVRC6; } -const char* DivPlatformVRC6::getEffectName(unsigned char effect) { - switch (effect) { - case 0x12: - return "12xx: Set duty cycle (pulse: 0 to 7)"; - break; - case 0x17: - return "17xx: Toggle PCM mode (pulse channel)"; - break; - } - return NULL; -} - void DivPlatformVRC6::acquire(short* bufL, short* bufR, size_t start, size_t len) { for (size_t i=start; i& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); DivPlatformVRC6() : vrc6(intf) {}; diff --git a/src/engine/platform/x1_010.cpp b/src/engine/platform/x1_010.cpp index e2e360b1b..f6aa1c651 100644 --- a/src/engine/platform/x1_010.cpp +++ b/src/engine/platform/x1_010.cpp @@ -205,39 +205,6 @@ const char** DivPlatformX1_010::getRegisterSheet() { return regCheatSheetX1_010; } -const char* DivPlatformX1_010::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xx: Change waveform"; - break; - case 0x11: - return "11xx: Change envelope shape"; - break; - case 0x17: - return "17xx: Toggle PCM mode"; - break; - case 0x20: - return "20xx: Set PCM frequency (1 to FF)"; - break; - case 0x22: - return "22xx: Set envelope mode (bit 0: enable, bit 1: one-shot, bit 2: split shape to L/R, bit 3/5: H.invert right/left, bit 4/6: V.invert right/left)"; - break; - case 0x23: - return "23xx: Set envelope period"; - break; - case 0x25: - return "25xx: Envelope slide up"; - break; - case 0x26: - return "26xx: Envelope slide down"; - break; - case 0x29: - return "29xy: Set auto-envelope (x: numerator; y: denominator)"; - break; - } - return NULL; -} - void DivPlatformX1_010::acquire(short* bufL, short* bufR, size_t start, size_t len) { for (size_t h=start; htick(); diff --git a/src/engine/platform/x1_010.h b/src/engine/platform/x1_010.h index 7a85b6336..178a89383 100644 --- a/src/engine/platform/x1_010.h +++ b/src/engine/platform/x1_010.h @@ -149,7 +149,6 @@ class DivPlatformX1_010: public DivDispatch { size_t getSampleMemUsage(int index = 0); void renderSamples(); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformX1_010(); diff --git a/src/engine/platform/ym2203.cpp b/src/engine/platform/ym2203.cpp index 83c93c58e..afb4f526c 100644 --- a/src/engine/platform/ym2203.cpp +++ b/src/engine/platform/ym2203.cpp @@ -156,123 +156,6 @@ const char** DivPlatformYM2203::getRegisterSheet() { return regCheatSheetYM2203; } -const char* DivPlatformYM2203::getEffectName(unsigned char effect) { - switch (effect) { - case 0x11: - return "11xx: Set feedback (0 to 7)"; - break; - case 0x12: - return "12xx: Set level of operator 1 (0 highest, 7F lowest)"; - break; - case 0x13: - return "13xx: Set level of operator 2 (0 highest, 7F lowest)"; - break; - case 0x14: - return "14xx: Set level of operator 3 (0 highest, 7F lowest)"; - break; - case 0x15: - return "15xx: Set level of operator 4 (0 highest, 7F lowest)"; - break; - case 0x16: - return "16xy: Set operator multiplier (x: operator from 1 to 4; y: multiplier)"; - break; - case 0x18: - return "18xx: Toggle extended channel 3 mode"; - break; - case 0x19: - return "19xx: Set attack of all operators (0 to 1F)"; - break; - case 0x1a: - return "1Axx: Set attack of operator 1 (0 to 1F)"; - break; - case 0x1b: - return "1Bxx: Set attack of operator 2 (0 to 1F)"; - break; - case 0x1c: - return "1Cxx: Set attack of operator 3 (0 to 1F)"; - break; - case 0x1d: - return "1Dxx: Set attack of operator 4 (0 to 1F)"; - break; - case 0x20: - return "20xx: Set SSG channel mode (bit 0: square; bit 1: noise; bit 2: envelope)"; - break; - case 0x21: - return "21xx: Set SSG noise frequency (0 to 1F)"; - break; - case 0x22: - return "22xy: Set SSG envelope mode (x: shape, y: enable for this channel)"; - break; - case 0x23: - return "23xx: Set SSG envelope period low byte"; - break; - case 0x24: - return "24xx: Set SSG envelope period high byte"; - break; - case 0x25: - return "25xx: SSG envelope slide up"; - break; - case 0x26: - return "26xx: SSG envelope slide down"; - break; - case 0x29: - return "29xy: Set SSG auto-envelope (x: numerator; y: denominator)"; - break; - case 0x30: - return "30xx: Toggle hard envelope reset on new notes"; - break; - case 0x50: - return "50xy: Set AM (x: operator from 1 to 4 (0 for all ops); y: AM)"; - break; - case 0x51: - return "51xy: Set sustain level (x: operator from 1 to 4 (0 for all ops); y: sustain)"; - break; - case 0x52: - return "52xy: Set release (x: operator from 1 to 4 (0 for all ops); y: release)"; - break; - case 0x53: - return "53xy: Set detune (x: operator from 1 to 4 (0 for all ops); y: detune where 3 is center)"; - break; - case 0x54: - return "54xy: Set envelope scale (x: operator from 1 to 4 (0 for all ops); y: scale from 0 to 3)"; - break; - case 0x55: - return "55xy: Set SSG envelope (x: operator from 1 to 4 (0 for all ops); y: 0-7 on, 8 off)"; - break; - case 0x56: - return "56xx: Set decay of all operators (0 to 1F)"; - break; - case 0x57: - return "57xx: Set decay of operator 1 (0 to 1F)"; - break; - case 0x58: - return "58xx: Set decay of operator 2 (0 to 1F)"; - break; - case 0x59: - return "59xx: Set decay of operator 3 (0 to 1F)"; - break; - case 0x5a: - return "5Axx: Set decay of operator 4 (0 to 1F)"; - break; - case 0x5b: - return "5Bxx: Set decay 2 of all operators (0 to 1F)"; - break; - case 0x5c: - return "5Cxx: Set decay 2 of operator 1 (0 to 1F)"; - break; - case 0x5d: - return "5Dxx: Set decay 2 of operator 2 (0 to 1F)"; - break; - case 0x5e: - return "5Exx: Set decay 2 of operator 3 (0 to 1F)"; - break; - case 0x5f: - return "5Fxx: Set decay 2 of operator 4 (0 to 1F)"; - break; - } - return NULL; -} - void DivPlatformYM2203::acquire(short* bufL, short* bufR, size_t start, size_t len) { static int os; diff --git a/src/engine/platform/ym2203.h b/src/engine/platform/ym2203.h index d406e2f28..0395c9d0f 100644 --- a/src/engine/platform/ym2203.h +++ b/src/engine/platform/ym2203.h @@ -114,7 +114,6 @@ class DivPlatformYM2203: public DivPlatformOPN { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); void setFlags(unsigned int flags); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index c3cf52a06..9e76e6e3f 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -279,126 +279,6 @@ const char** DivPlatformYM2608::getRegisterSheet() { return regCheatSheetYM2608; } -const char* DivPlatformYM2608::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xy: Setup LFO (x: enable; y: speed)"; - break; - case 0x11: - return "11xx: Set feedback (0 to 7)"; - break; - case 0x12: - return "12xx: Set level of operator 1 (0 highest, 7F lowest)"; - break; - case 0x13: - return "13xx: Set level of operator 2 (0 highest, 7F lowest)"; - break; - case 0x14: - return "14xx: Set level of operator 3 (0 highest, 7F lowest)"; - break; - case 0x15: - return "15xx: Set level of operator 4 (0 highest, 7F lowest)"; - break; - case 0x16: - return "16xy: Set operator multiplier (x: operator from 1 to 4; y: multiplier)"; - break; - case 0x18: - return "18xx: Toggle extended channel 3 mode"; - break; - case 0x19: - return "19xx: Set attack of all operators (0 to 1F)"; - break; - case 0x1a: - return "1Axx: Set attack of operator 1 (0 to 1F)"; - break; - case 0x1b: - return "1Bxx: Set attack of operator 2 (0 to 1F)"; - break; - case 0x1c: - return "1Cxx: Set attack of operator 3 (0 to 1F)"; - break; - case 0x1d: - return "1Dxx: Set attack of operator 4 (0 to 1F)"; - break; - case 0x20: - return "20xx: Set SSG channel mode (bit 0: square; bit 1: noise; bit 2: envelope)"; - break; - case 0x21: - return "21xx: Set SSG noise frequency (0 to 1F)"; - break; - case 0x22: - return "22xy: Set SSG envelope mode (x: shape, y: enable for this channel)"; - break; - case 0x23: - return "23xx: Set SSG envelope period low byte"; - break; - case 0x24: - return "24xx: Set SSG envelope period high byte"; - break; - case 0x25: - return "25xx: SSG envelope slide up"; - break; - case 0x26: - return "26xx: SSG envelope slide down"; - break; - case 0x29: - return "29xy: Set SSG auto-envelope (x: numerator; y: denominator)"; - break; - case 0x30: - return "30xx: Toggle hard envelope reset on new notes"; - break; - case 0x50: - return "50xy: Set AM (x: operator from 1 to 4 (0 for all ops); y: AM)"; - break; - case 0x51: - return "51xy: Set sustain level (x: operator from 1 to 4 (0 for all ops); y: sustain)"; - break; - case 0x52: - return "52xy: Set release (x: operator from 1 to 4 (0 for all ops); y: release)"; - break; - case 0x53: - return "53xy: Set detune (x: operator from 1 to 4 (0 for all ops); y: detune where 3 is center)"; - break; - case 0x54: - return "54xy: Set envelope scale (x: operator from 1 to 4 (0 for all ops); y: scale from 0 to 3)"; - break; - case 0x55: - return "55xy: Set SSG envelope (x: operator from 1 to 4 (0 for all ops); y: 0-7 on, 8 off)"; - break; - case 0x56: - return "56xx: Set decay of all operators (0 to 1F)"; - break; - case 0x57: - return "57xx: Set decay of operator 1 (0 to 1F)"; - break; - case 0x58: - return "58xx: Set decay of operator 2 (0 to 1F)"; - break; - case 0x59: - return "59xx: Set decay of operator 3 (0 to 1F)"; - break; - case 0x5a: - return "5Axx: Set decay of operator 4 (0 to 1F)"; - break; - case 0x5b: - return "5Bxx: Set decay 2 of all operators (0 to 1F)"; - break; - case 0x5c: - return "5Cxx: Set decay 2 of operator 1 (0 to 1F)"; - break; - case 0x5d: - return "5Dxx: Set decay 2 of operator 2 (0 to 1F)"; - break; - case 0x5e: - return "5Exx: Set decay 2 of operator 3 (0 to 1F)"; - break; - case 0x5f: - return "5Fxx: Set decay 2 of operator 4 (0 to 1F)"; - break; - } - return NULL; -} - double DivPlatformYM2608::NOTE_OPNB(int ch, int note) { if (ch>8) { // ADPCM-B return NOTE_ADPCMB(note); diff --git a/src/engine/platform/ym2608.h b/src/engine/platform/ym2608.h index ac38a8c08..7a471b8bf 100644 --- a/src/engine/platform/ym2608.h +++ b/src/engine/platform/ym2608.h @@ -127,7 +127,6 @@ class DivPlatformYM2608: public DivPlatformOPN { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); const void* getSampleMem(int index); size_t getSampleMemCapacity(int index); size_t getSampleMemUsage(int index); diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 4e01b005c..920d9b144 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -318,126 +318,6 @@ const char** DivPlatformYM2610::getRegisterSheet() { return regCheatSheetYM2610; } -const char* DivPlatformYM2610::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xy: Setup LFO (x: enable; y: speed)"; - break; - case 0x11: - return "11xx: Set feedback (0 to 7)"; - break; - case 0x12: - return "12xx: Set level of operator 1 (0 highest, 7F lowest)"; - break; - case 0x13: - return "13xx: Set level of operator 2 (0 highest, 7F lowest)"; - break; - case 0x14: - return "14xx: Set level of operator 3 (0 highest, 7F lowest)"; - break; - case 0x15: - return "15xx: Set level of operator 4 (0 highest, 7F lowest)"; - break; - case 0x16: - return "16xy: Set operator multiplier (x: operator from 1 to 4; y: multiplier)"; - break; - case 0x18: - return "18xx: Toggle extended channel 3 mode"; - break; - case 0x19: - return "19xx: Set attack of all operators (0 to 1F)"; - break; - case 0x1a: - return "1Axx: Set attack of operator 1 (0 to 1F)"; - break; - case 0x1b: - return "1Bxx: Set attack of operator 2 (0 to 1F)"; - break; - case 0x1c: - return "1Cxx: Set attack of operator 3 (0 to 1F)"; - break; - case 0x1d: - return "1Dxx: Set attack of operator 4 (0 to 1F)"; - break; - case 0x20: - return "20xx: Set SSG channel mode (bit 0: square; bit 1: noise; bit 2: envelope)"; - break; - case 0x21: - return "21xx: Set SSG noise frequency (0 to 1F)"; - break; - case 0x22: - return "22xy: Set SSG envelope mode (x: shape, y: enable for this channel)"; - break; - case 0x23: - return "23xx: Set SSG envelope period low byte"; - break; - case 0x24: - return "24xx: Set SSG envelope period high byte"; - break; - case 0x25: - return "25xx: SSG envelope slide up"; - break; - case 0x26: - return "26xx: SSG envelope slide down"; - break; - case 0x29: - return "29xy: Set SSG auto-envelope (x: numerator; y: denominator)"; - break; - case 0x30: - return "30xx: Toggle hard envelope reset on new notes"; - break; - case 0x50: - return "50xy: Set AM (x: operator from 1 to 4 (0 for all ops); y: AM)"; - break; - case 0x51: - return "51xy: Set sustain level (x: operator from 1 to 4 (0 for all ops); y: sustain)"; - break; - case 0x52: - return "52xy: Set release (x: operator from 1 to 4 (0 for all ops); y: release)"; - break; - case 0x53: - return "53xy: Set detune (x: operator from 1 to 4 (0 for all ops); y: detune where 3 is center)"; - break; - case 0x54: - return "54xy: Set envelope scale (x: operator from 1 to 4 (0 for all ops); y: scale from 0 to 3)"; - break; - case 0x55: - return "55xy: Set SSG envelope (x: operator from 1 to 4 (0 for all ops); y: 0-7 on, 8 off)"; - break; - case 0x56: - return "56xx: Set decay of all operators (0 to 1F)"; - break; - case 0x57: - return "57xx: Set decay of operator 1 (0 to 1F)"; - break; - case 0x58: - return "58xx: Set decay of operator 2 (0 to 1F)"; - break; - case 0x59: - return "59xx: Set decay of operator 3 (0 to 1F)"; - break; - case 0x5a: - return "5Axx: Set decay of operator 4 (0 to 1F)"; - break; - case 0x5b: - return "5Bxx: Set decay 2 of all operators (0 to 1F)"; - break; - case 0x5c: - return "5Cxx: Set decay 2 of operator 1 (0 to 1F)"; - break; - case 0x5d: - return "5Dxx: Set decay 2 of operator 2 (0 to 1F)"; - break; - case 0x5e: - return "5Exx: Set decay 2 of operator 3 (0 to 1F)"; - break; - case 0x5f: - return "5Fxx: Set decay 2 of operator 4 (0 to 1F)"; - break; - } - return NULL; -} - double DivPlatformYM2610::NOTE_OPNB(int ch, int note) { if (ch>6) { // ADPCM return NOTE_ADPCMB(note); diff --git a/src/engine/platform/ym2610.h b/src/engine/platform/ym2610.h index dde7ed105..5e22ed2a0 100644 --- a/src/engine/platform/ym2610.h +++ b/src/engine/platform/ym2610.h @@ -145,7 +145,6 @@ class DivPlatformYM2610: public DivPlatformYM2610Base { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); void setFlags(unsigned int flags); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 1a1f7f0ae..039691e74 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -302,126 +302,6 @@ const char** DivPlatformYM2610B::getRegisterSheet() { return regCheatSheetYM2610B; } -const char* DivPlatformYM2610B::getEffectName(unsigned char effect) { - switch (effect) { - case 0x10: - return "10xy: Setup LFO (x: enable; y: speed)"; - break; - case 0x11: - return "11xx: Set feedback (0 to 7)"; - break; - case 0x12: - return "12xx: Set level of operator 1 (0 highest, 7F lowest)"; - break; - case 0x13: - return "13xx: Set level of operator 2 (0 highest, 7F lowest)"; - break; - case 0x14: - return "14xx: Set level of operator 3 (0 highest, 7F lowest)"; - break; - case 0x15: - return "15xx: Set level of operator 4 (0 highest, 7F lowest)"; - break; - case 0x16: - return "16xy: Set operator multiplier (x: operator from 1 to 4; y: multiplier)"; - break; - case 0x18: - return "18xx: Toggle extended channel 3 mode"; - break; - case 0x19: - return "19xx: Set attack of all operators (0 to 1F)"; - break; - case 0x1a: - return "1Axx: Set attack of operator 1 (0 to 1F)"; - break; - case 0x1b: - return "1Bxx: Set attack of operator 2 (0 to 1F)"; - break; - case 0x1c: - return "1Cxx: Set attack of operator 3 (0 to 1F)"; - break; - case 0x1d: - return "1Dxx: Set attack of operator 4 (0 to 1F)"; - break; - case 0x20: - return "20xx: Set SSG channel mode (bit 0: square; bit 1: noise; bit 2: envelope)"; - break; - case 0x21: - return "21xx: Set SSG noise frequency (0 to 1F)"; - break; - case 0x22: - return "22xy: Set SSG envelope mode (x: shape, y: enable for this channel)"; - break; - case 0x23: - return "23xx: Set SSG envelope period low byte"; - break; - case 0x24: - return "24xx: Set SSG envelope period high byte"; - break; - case 0x25: - return "25xx: SSG envelope slide up"; - break; - case 0x26: - return "26xx: SSG envelope slide down"; - break; - case 0x29: - return "29xy: Set SSG auto-envelope (x: numerator; y: denominator)"; - break; - case 0x30: - return "30xx: Toggle hard envelope reset on new notes"; - break; - case 0x50: - return "50xy: Set AM (x: operator from 1 to 4 (0 for all ops); y: AM)"; - break; - case 0x51: - return "51xy: Set sustain level (x: operator from 1 to 4 (0 for all ops); y: sustain)"; - break; - case 0x52: - return "52xy: Set release (x: operator from 1 to 4 (0 for all ops); y: release)"; - break; - case 0x53: - return "53xy: Set detune (x: operator from 1 to 4 (0 for all ops); y: detune where 3 is center)"; - break; - case 0x54: - return "54xy: Set envelope scale (x: operator from 1 to 4 (0 for all ops); y: scale from 0 to 3)"; - break; - case 0x55: - return "55xy: Set SSG envelope (x: operator from 1 to 4 (0 for all ops); y: 0-7 on, 8 off)"; - break; - case 0x56: - return "56xx: Set decay of all operators (0 to 1F)"; - break; - case 0x57: - return "57xx: Set decay of operator 1 (0 to 1F)"; - break; - case 0x58: - return "58xx: Set decay of operator 2 (0 to 1F)"; - break; - case 0x59: - return "59xx: Set decay of operator 3 (0 to 1F)"; - break; - case 0x5a: - return "5Axx: Set decay of operator 4 (0 to 1F)"; - break; - case 0x5b: - return "5Bxx: Set decay 2 of all operators (0 to 1F)"; - break; - case 0x5c: - return "5Cxx: Set decay 2 of operator 1 (0 to 1F)"; - break; - case 0x5d: - return "5Dxx: Set decay 2 of operator 2 (0 to 1F)"; - break; - case 0x5e: - return "5Exx: Set decay 2 of operator 3 (0 to 1F)"; - break; - case 0x5f: - return "5Fxx: Set decay 2 of operator 4 (0 to 1F)"; - break; - } - return NULL; -} - double DivPlatformYM2610B::NOTE_OPNB(int ch, int note) { if (ch>8) { // ADPCM-B return NOTE_ADPCMB(note); diff --git a/src/engine/platform/ym2610b.h b/src/engine/platform/ym2610b.h index fefb06929..703f8dd4a 100644 --- a/src/engine/platform/ym2610b.h +++ b/src/engine/platform/ym2610b.h @@ -113,7 +113,6 @@ class DivPlatformYM2610B: public DivPlatformYM2610Base { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); void setFlags(unsigned int flags); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); diff --git a/src/engine/platform/ymz280b.cpp b/src/engine/platform/ymz280b.cpp index 0543a815c..ca1b225d2 100644 --- a/src/engine/platform/ymz280b.cpp +++ b/src/engine/platform/ymz280b.cpp @@ -60,10 +60,6 @@ const char** DivPlatformYMZ280B::getRegisterSheet() { return regCheatSheetYMZ280B; } -const char* DivPlatformYMZ280B::getEffectName(unsigned char effect) { - return NULL; -} - void DivPlatformYMZ280B::acquire(short* bufL, short* bufR, size_t start, size_t len) { short buf[16][256]; short *bufPtrs[16]={ diff --git a/src/engine/platform/ymz280b.h b/src/engine/platform/ymz280b.h index 0d254c088..6dbe2623c 100644 --- a/src/engine/platform/ymz280b.h +++ b/src/engine/platform/ymz280b.h @@ -91,7 +91,6 @@ class DivPlatformYMZ280B: public DivDispatch { void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); const void* getSampleMem(int index = 0); size_t getSampleMemCapacity(int index = 0); size_t getSampleMemUsage(int index = 0); diff --git a/src/engine/platform/zxbeeper.cpp b/src/engine/platform/zxbeeper.cpp index 01702dc5d..d83903094 100644 --- a/src/engine/platform/zxbeeper.cpp +++ b/src/engine/platform/zxbeeper.cpp @@ -27,18 +27,6 @@ const char** DivPlatformZXBeeper::getRegisterSheet() { return NULL; } -const char* DivPlatformZXBeeper::getEffectName(unsigned char effect) { - switch (effect) { - case 0x12: - return "12xx: Set pulse width"; - break; - case 0x17: - return "17xx: Trigger overlay drum"; - break; - } - return NULL; -} - void DivPlatformZXBeeper::acquire(short* bufL, short* bufR, size_t start, size_t len) { bool o=false; for (size_t h=start; h& wlist); const char** getRegisterSheet(); - const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformZXBeeper(); diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 3dbc6b5fb..63203ab54 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -292,13 +292,39 @@ int DivEngine::dispatchCmd(DivCommand c) { } bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effectVal) { - if (sysDefs[sysOfChan[ch]]==NULL) return false; - return sysDefs[sysOfChan[ch]]->effectFunc(ch,effect,effectVal); + DivSysDef* sysDef=sysDefs[sysOfChan[ch]]; + if (sysDef==NULL) return false; + auto iter=sysDef->effectHandlers.find(effect); + if (iter==sysDef->effectHandlers.end()) return false; + EffectHandler handler=iter->second; + int val=0; + int val2=0; + try { + val=handler.val?handler.val(effect,effectVal):effectVal; + val2=handler.val2?handler.val2(effect,effectVal):0; + } catch (DivDoNotHandleEffect& e) { + return false; + } + // wouldn't this cause problems if it were to return 0? + return dispatchCmd(DivCommand(handler.dispatchCmd,ch,val,val2)); } bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char effectVal) { - if (sysDefs[sysOfChan[ch]]==NULL) return false; - return sysDefs[sysOfChan[ch]]->postEffectFunc(ch,effect,effectVal); + DivSysDef* sysDef=sysDefs[sysOfChan[ch]]; + if (sysDef==NULL) return false; + auto iter=sysDef->postEffectHandlers.find(effect); + if (iter==sysDef->postEffectHandlers.end()) return false; + EffectHandler handler=iter->second; + int val=0; + int val2=0; + try { + val=handler.val?handler.val(effect,effectVal):effectVal; + val2=handler.val2?handler.val2(effect,effectVal):0; + } catch (DivDoNotHandleEffect& e) { + return true; + } + // wouldn't this cause problems if it were to return 0? + return dispatchCmd(DivCommand(handler.dispatchCmd,ch,val,val2)); } void DivEngine::processRow(int i, bool afterDelay) { @@ -609,9 +635,6 @@ void DivEngine::processRow(int i, bool afterDelay) { clockDrift=0; subticks=0; break; - case 0xdf: // set sample direction - dispatchCmd(DivCommand(DIV_CMD_SAMPLE_DIR,i,effectVal)); - break; case 0xe0: // arp speed if (effectVal>0) { curSubSong->arpLen=effectVal; diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index e3c356cf7..63cb6faca 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -360,390 +360,222 @@ int DivEngine::minVGMVersion(DivSystem which) { // {chanTypes, ...}, // {chanPreferInsType, ...}, // {chanPreferInsType2, ...}, (optional) -// [this](int ch, unsigned char effect, unsigned char effectVal) -> bool {}, (effect handler, optional) -// [this](int ch, unsigned char effect, unsigned char effectVal) -> bool {} (post effect handler, optional) +// {{effect, {DIV_CMD_xx, "Description"}}, ...}, (effect handler, optional) +// {{effect, {DIV_CMD_xx, "Description"}}, ...} (post effect handler, optional) // ); +template int constVal(unsigned char, unsigned char) { + return val; +}; + +int effectVal(unsigned char, unsigned char val) { + return val; +}; + +int negEffectVal(unsigned char, unsigned char val) { + return -(int)val; +}; + +template int effectValAnd(unsigned char, unsigned char val) { + return val&mask; +}; + +template int effectOpVal(unsigned char, unsigned char val) { + if ((val>>4)>maxOp) throw DivDoNotHandleEffect(); + return (val>>4)-1; +}; + +template int effectOpValNoZero(unsigned char, unsigned char val) { + if ((val>>4)<1 || (val>>4)>maxOp) throw DivDoNotHandleEffect(); + return (val>>4)-1; +}; + +template int effectValLong(unsigned char cmd, unsigned char val) { + return ((((unsigned int)cmd)&((1<<(bits-8))-1))<<8)|((unsigned int)val); +}; + void DivEngine::registerSystems() { logD("registering systems..."); - auto fmPostEffectHandler=[this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x10: // LFO or noise mode - if (IS_OPM_LIKE) { - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_FREQ,ch,effectVal)); - } else { - dispatchCmd(DivCommand(DIV_CMD_FM_LFO,ch,effectVal)); - } - break; - case 0x11: // FB - dispatchCmd(DivCommand(DIV_CMD_FM_FB,ch,effectVal&7)); - break; - case 0x12: // TL op1 - dispatchCmd(DivCommand(DIV_CMD_FM_TL,ch,0,effectVal&0x7f)); - break; - case 0x13: // TL op2 - dispatchCmd(DivCommand(DIV_CMD_FM_TL,ch,1,effectVal&0x7f)); - break; - case 0x14: // TL op3 - dispatchCmd(DivCommand(DIV_CMD_FM_TL,ch,2,effectVal&0x7f)); - break; - case 0x15: // TL op4 - dispatchCmd(DivCommand(DIV_CMD_FM_TL,ch,3,effectVal&0x7f)); - break; - case 0x16: // MULT - if ((effectVal>>4)>0 && (effectVal>>4)<5) { - dispatchCmd(DivCommand(DIV_CMD_FM_MULT,ch,(effectVal>>4)-1,effectVal&15)); - } - break; - case 0x17: // arcade LFO - if (IS_OPM_LIKE) { - dispatchCmd(DivCommand(DIV_CMD_FM_LFO,ch,effectVal)); - } - break; - case 0x18: // EXT or LFO waveform - if (IS_OPM_LIKE) { - dispatchCmd(DivCommand(DIV_CMD_FM_LFO_WAVE,ch,effectVal)); - } else { - dispatchCmd(DivCommand(DIV_CMD_FM_EXTCH,ch,effectVal)); - } - break; - case 0x19: // AR global - dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,-1,effectVal&31)); - break; - case 0x1a: // AR op1 - dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,0,effectVal&31)); - break; - case 0x1b: // AR op2 - dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,1,effectVal&31)); - break; - case 0x1c: // AR op3 - dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,2,effectVal&31)); - break; - case 0x1d: // AR op4 - dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,3,effectVal&31)); - break; - case 0x1e: // UNOFFICIAL: Arcade AM depth - dispatchCmd(DivCommand(DIV_CMD_FM_AM_DEPTH,ch,effectVal&127)); - break; - case 0x1f: // UNOFFICIAL: Arcade PM depth - dispatchCmd(DivCommand(DIV_CMD_FM_PM_DEPTH,ch,effectVal&127)); - break; - case 0x20: // Neo Geo PSG mode - if (IS_YM2610) { - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); - } - break; - case 0x21: // Neo Geo PSG noise freq - if (IS_YM2610) { - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_FREQ,ch,effectVal)); - } - break; - case 0x22: // UNOFFICIAL: Neo Geo PSG envelope enable - if (IS_YM2610) { - dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_SET,ch,effectVal)); - } - break; - case 0x23: // UNOFFICIAL: Neo Geo PSG envelope period low - if (IS_YM2610) { - dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_LOW,ch,effectVal)); - } - break; - case 0x24: // UNOFFICIAL: Neo Geo PSG envelope period high - if (IS_YM2610) { - dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_HIGH,ch,effectVal)); - } - break; - case 0x25: // UNOFFICIAL: Neo Geo PSG envelope slide up - if (IS_YM2610) { - dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_SLIDE,ch,-effectVal)); - } - break; - case 0x26: // UNOFFICIAL: Neo Geo PSG envelope slide down - if (IS_YM2610) { - dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_SLIDE,ch,effectVal)); - } - break; - case 0x29: // auto-envelope - if (IS_YM2610) { - dispatchCmd(DivCommand(DIV_CMD_AY_AUTO_ENVELOPE,ch,effectVal)); - } - break; - // fixed frequency effects on OPZ - case 0x30: case 0x31: case 0x32: case 0x33: - case 0x34: case 0x35: case 0x36: case 0x37: - if (sysOfChan[ch]==DIV_SYSTEM_OPZ) { - dispatchCmd(DivCommand(DIV_CMD_FM_FIXFREQ,ch,0,((effect&7)<<8)|effectVal)); - } - break; - case 0x38: case 0x39: case 0x3a: case 0x3b: - case 0x3c: case 0x3d: case 0x3e: case 0x3f: - if (sysOfChan[ch]==DIV_SYSTEM_OPZ) { - dispatchCmd(DivCommand(DIV_CMD_FM_FIXFREQ,ch,1,((effect&7)<<8)|effectVal)); - } - break; - case 0x40: case 0x41: case 0x42: case 0x43: - case 0x44: case 0x45: case 0x46: case 0x47: - if (sysOfChan[ch]==DIV_SYSTEM_OPZ) { - dispatchCmd(DivCommand(DIV_CMD_FM_FIXFREQ,ch,2,((effect&7)<<8)|effectVal)); - } - break; - case 0x48: case 0x49: case 0x4a: case 0x4b: - case 0x4c: case 0x4d: case 0x4e: case 0x4f: - if (sysOfChan[ch]==DIV_SYSTEM_OPZ) { - dispatchCmd(DivCommand(DIV_CMD_FM_FIXFREQ,ch,3,((effect&7)<<8)|effectVal)); - } - break; - // extra FM effects here - OP_EFFECT_SINGLE(0x50,DIV_CMD_FM_AM,4,1); - OP_EFFECT_SINGLE(0x51,DIV_CMD_FM_SL,4,15); - OP_EFFECT_SINGLE(0x52,DIV_CMD_FM_RR,4,15); - OP_EFFECT_SINGLE(0x53,DIV_CMD_FM_DT,4,7); - OP_EFFECT_SINGLE(0x54,DIV_CMD_FM_RS,4,3); - OP_EFFECT_SINGLE(0x55,DIV_CMD_FM_SSG,4,(IS_OPM_LIKE?3:15)); + // Common effect handler maps - OP_EFFECT_MULTI(0x56,DIV_CMD_FM_DR,-1,31); - OP_EFFECT_MULTI(0x57,DIV_CMD_FM_DR,0,31); - OP_EFFECT_MULTI(0x58,DIV_CMD_FM_DR,1,31); - OP_EFFECT_MULTI(0x59,DIV_CMD_FM_DR,2,31); - OP_EFFECT_MULTI(0x5a,DIV_CMD_FM_DR,3,31); - - OP_EFFECT_MULTI(0x5b,DIV_CMD_FM_D2R,-1,31); - OP_EFFECT_MULTI(0x5c,DIV_CMD_FM_D2R,0,31); - OP_EFFECT_MULTI(0x5d,DIV_CMD_FM_D2R,1,31); - OP_EFFECT_MULTI(0x5e,DIV_CMD_FM_D2R,2,31); - OP_EFFECT_MULTI(0x5f,DIV_CMD_FM_D2R,3,31); - - OP_EFFECT_SINGLE(0x28,DIV_CMD_FM_REV,4,7); - OP_EFFECT_SINGLE(0x2a,DIV_CMD_FM_WS,4,7); - OP_EFFECT_SINGLE(0x2b,DIV_CMD_FM_EG_SHIFT,4,3); - OP_EFFECT_SINGLE(0x2c,DIV_CMD_FM_FINE,4,15); - default: - return false; - } - return true; + EffectHandlerMap ayPostEffectHandlerMap={ + {0x20, {DIV_CMD_STD_NOISE_MODE, "20xx: Set channel mode (bit 0: square; bit 1: noise; bit 2: envelope)"}}, + {0x21, {DIV_CMD_STD_NOISE_FREQ, "21xx: Set noise frequency (0 to 1F)"}}, + {0x22, {DIV_CMD_AY_ENVELOPE_SET, "22xy: Set envelope mode (x: shape, y: enable for this channel)"}}, + {0x23, {DIV_CMD_AY_ENVELOPE_LOW, "23xx: Set envelope period low byte"}}, + {0x24, {DIV_CMD_AY_ENVELOPE_HIGH, "24xx: Set envelope period high byte"}}, + {0x25, {DIV_CMD_AY_ENVELOPE_SLIDE, "25xx: Envelope slide up", negEffectVal}}, + {0x26, {DIV_CMD_AY_ENVELOPE_SLIDE, "26xx: Envelope slide down"}}, + {0x29, {DIV_CMD_AY_AUTO_ENVELOPE, "29xy: Set auto-envelope (x: numerator; y: denominator)"}}, + {0x2e, {DIV_CMD_AY_IO_WRITE, "2Exx: Write to I/O port A", constVal<0>, effectVal}}, + {0x2f, {DIV_CMD_AY_IO_WRITE, "2Fxx: Write to I/O port B", constVal<1>, effectVal}}, }; - auto fmOPLLPostEffectHandler=[this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x11: // FB - dispatchCmd(DivCommand(DIV_CMD_FM_FB,ch,effectVal&7)); - break; - case 0x12: // TL op1 - dispatchCmd(DivCommand(DIV_CMD_FM_TL,ch,0,effectVal&0x3f)); - break; - case 0x13: // TL op2 - dispatchCmd(DivCommand(DIV_CMD_FM_TL,ch,1,effectVal&0x0f)); - break; - case 0x16: // MULT - if ((effectVal>>4)>0 && (effectVal>>4)<3) { - dispatchCmd(DivCommand(DIV_CMD_FM_MULT,ch,(effectVal>>4)-1,effectVal&15)); - } - break; - case 0x19: // AR global - dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,-1,effectVal&31)); - break; - case 0x1a: // AR op1 - dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,0,effectVal&31)); - break; - case 0x1b: // AR op2 - dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,1,effectVal&31)); - break; + EffectHandlerMap ay8930PostEffectHandlerMap(ayPostEffectHandlerMap); + ay8930PostEffectHandlerMap.insert({ + {0x12, {DIV_CMD_STD_NOISE_MODE, "12xx: Set duty cycle (0 to 8)", + [](unsigned char, unsigned char val) -> int { return 0x10+(val&15); }}}, + {0x27, {DIV_CMD_AY_NOISE_MASK_AND, "27xx: Set noise AND mask"}}, + {0x28, {DIV_CMD_AY_NOISE_MASK_OR, "28xx: Set noise OR mask"}}, + {0x2d, {DIV_CMD_AY_IO_WRITE, "2Dxx: NOT TO BE EMPLOYED BY THE COMPOSER", constVal<255>, effectVal}}, + }); - // extra FM effects here - OP_EFFECT_SINGLE(0x50,DIV_CMD_FM_AM,2,1); - OP_EFFECT_SINGLE(0x51,DIV_CMD_FM_SL,2,15); - OP_EFFECT_SINGLE(0x52,DIV_CMD_FM_RR,2,15); - OP_EFFECT_SINGLE(0x53,DIV_CMD_FM_VIB,2,1); - OP_EFFECT_SINGLE(0x54,DIV_CMD_FM_RS,2,3); - OP_EFFECT_SINGLE(0x55,DIV_CMD_FM_SUS,2,1); - - OP_EFFECT_MULTI(0x56,DIV_CMD_FM_DR,-1,15); - OP_EFFECT_MULTI(0x57,DIV_CMD_FM_DR,0,15); - OP_EFFECT_MULTI(0x58,DIV_CMD_FM_DR,1,15); - - OP_EFFECT_SINGLE(0x5b,DIV_CMD_FM_KSR,2,1); - default: - return false; - } - return true; + EffectHandlerMap fmEffectHandlerMap={ + {0x30, {DIV_CMD_FM_HARD_RESET, "30xx: Toggle hard envelope reset on new notes"}}, }; - auto fmOPLPostEffectHandler=[this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x10: // DAM - dispatchCmd(DivCommand(DIV_CMD_FM_LFO,ch,effectVal&1)); - break; - case 0x11: // FB - dispatchCmd(DivCommand(DIV_CMD_FM_FB,ch,effectVal&7)); - break; - case 0x12: // TL op1 - dispatchCmd(DivCommand(DIV_CMD_FM_TL,ch,0,effectVal&0x3f)); - break; - case 0x13: // TL op2 - dispatchCmd(DivCommand(DIV_CMD_FM_TL,ch,1,effectVal&0x3f)); - break; - case 0x14: // TL op3 - dispatchCmd(DivCommand(DIV_CMD_FM_TL,ch,2,effectVal&0x3f)); - break; - case 0x15: // TL op4 - dispatchCmd(DivCommand(DIV_CMD_FM_TL,ch,3,effectVal&0x3f)); - break; - case 0x16: // MULT - if ((effectVal>>4)>0 && (effectVal>>4)<5) { - dispatchCmd(DivCommand(DIV_CMD_FM_MULT,ch,(effectVal>>4)-1,effectVal&15)); - } - break; - case 0x17: // DVB - dispatchCmd(DivCommand(DIV_CMD_FM_LFO,ch,2+(effectVal&1))); - break; - case 0x19: // AR global - dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,-1,effectVal&15)); - break; - case 0x1a: // AR op1 - dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,0,effectVal&15)); - break; - case 0x1b: // AR op2 - dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,1,effectVal&15)); - break; - case 0x1c: // AR op3 - dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,2,effectVal&15)); - break; - case 0x1d: // AR op4 - dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,3,effectVal&15)); - break; - - // extra FM effects here - OP_EFFECT_SINGLE(0x50,DIV_CMD_FM_AM,4,1); - OP_EFFECT_SINGLE(0x51,DIV_CMD_FM_SL,4,15); - OP_EFFECT_SINGLE(0x52,DIV_CMD_FM_RR,4,15); - OP_EFFECT_SINGLE(0x53,DIV_CMD_FM_VIB,4,1); - OP_EFFECT_SINGLE(0x54,DIV_CMD_FM_RS,4,3); - OP_EFFECT_SINGLE(0x55,DIV_CMD_FM_SUS,4,1); + EffectHandlerMap fmOPN2EffectHandlerMap(fmEffectHandlerMap); + fmOPN2EffectHandlerMap.insert({ + {0x17, {DIV_CMD_SAMPLE_MODE, "17xx: Toggle PCM mode"}}, + {0xdf, {DIV_CMD_SAMPLE_DIR, "DFxx: Set sample playback direction (0: normal; 1: reverse)"}}, + }); - OP_EFFECT_MULTI(0x56,DIV_CMD_FM_DR,-1,15); - OP_EFFECT_MULTI(0x57,DIV_CMD_FM_DR,0,15); - OP_EFFECT_MULTI(0x58,DIV_CMD_FM_DR,1,15); - OP_EFFECT_MULTI(0x59,DIV_CMD_FM_DR,2,15); - OP_EFFECT_MULTI(0x5a,DIV_CMD_FM_DR,3,15); + EffectHandlerMap fmOPLDrumsEffectHandlerMap(fmEffectHandlerMap); + fmOPLDrumsEffectHandlerMap.insert({ + {0x18, {DIV_CMD_FM_EXTCH, "18xx: Toggle drums mode (1: enabled; 0: disabled)"}}, + }); - OP_EFFECT_SINGLE(0x5b,DIV_CMD_FM_KSR,4,1); - OP_EFFECT_SINGLE(0x2a,DIV_CMD_FM_WS,4,7); - - default: - return false; - } - return true; + EffectHandlerMap fmOPNPostEffectHandlerMap={ + {0x11, {DIV_CMD_FM_FB, "11xx: Set feedback (0 to 7)"}}, + {0x12, {DIV_CMD_FM_TL, "12xx: Set level of operator 1 (0 highest, 7F lowest)", constVal<0>, effectVal}}, + {0x13, {DIV_CMD_FM_TL, "13xx: Set level of operator 2 (0 highest, 7F lowest)", constVal<1>, effectVal}}, + {0x14, {DIV_CMD_FM_TL, "14xx: Set level of operator 3 (0 highest, 7F lowest)", constVal<2>, effectVal}}, + {0x15, {DIV_CMD_FM_TL, "15xx: Set level of operator 4 (0 highest, 7F lowest)", constVal<3>, effectVal}}, + {0x16, {DIV_CMD_FM_MULT, "16xy: Set operator multiplier (x: operator from 1 to 4; y: multiplier)", effectOpValNoZero<4>, effectValAnd<15>}}, + {0x19, {DIV_CMD_FM_AR, "19xx: Set attack of all operators (0 to 1F)", constVal<-1>, effectValAnd<31>}}, + {0x1a, {DIV_CMD_FM_AR, "1Axx: Set attack of operator 1 (0 to 1F)", constVal<0>, effectValAnd<31>}}, + {0x1b, {DIV_CMD_FM_AR, "1Bxx: Set attack of operator 2 (0 to 1F)", constVal<1>, effectValAnd<31>}}, + {0x1c, {DIV_CMD_FM_AR, "1Cxx: Set attack of operator 3 (0 to 1F)", constVal<2>, effectValAnd<31>}}, + {0x1d, {DIV_CMD_FM_AR, "1Dxx: Set attack of operator 4 (0 to 1F)", constVal<3>, effectValAnd<31>}}, + {0x50, {DIV_CMD_FM_AM, "50xy: Set AM (x: operator from 1 to 4 (0 for all ops); y: AM)", effectOpVal<4>, effectValAnd<1>}}, + {0x51, {DIV_CMD_FM_SL, "51xy: Set sustain level (x: operator from 1 to 4 (0 for all ops); y: sustain)", effectOpVal<4>, effectValAnd<15>}}, + {0x52, {DIV_CMD_FM_RR, "52xy: Set release (x: operator from 1 to 4 (0 for all ops); y: release)", effectOpVal<4>, effectValAnd<15>}}, + {0x53, {DIV_CMD_FM_DT, "53xy: Set detune (x: operator from 1 to 4 (0 for all ops); y: detune where 3 is center)", effectOpVal<4>, effectValAnd<7>}}, + {0x54, {DIV_CMD_FM_RS, "54xy: Set envelope scale (x: operator from 1 to 4 (0 for all ops); y: scale from 0 to 3)", effectOpVal<4>, effectValAnd<3>}}, + {0x56, {DIV_CMD_FM_DR, "56xx: Set decay of all operators (0 to 1F)", constVal<-1>, effectValAnd<31>}}, + {0x57, {DIV_CMD_FM_DR, "57xx: Set decay of operator 1 (0 to 1F)", constVal<0>, effectValAnd<31>}}, + {0x58, {DIV_CMD_FM_DR, "58xx: Set decay of operator 2 (0 to 1F)", constVal<1>, effectValAnd<31>}}, + {0x59, {DIV_CMD_FM_DR, "59xx: Set decay of operator 3 (0 to 1F)", constVal<2>, effectValAnd<31>}}, + {0x5a, {DIV_CMD_FM_DR, "5Axx: Set decay of operator 4 (0 to 1F)", constVal<3>, effectValAnd<31>}}, + {0x5b, {DIV_CMD_FM_D2R, "5Bxx: Set decay 2 of all operators (0 to 1F)", constVal<-1>, effectValAnd<31>}}, + {0x5c, {DIV_CMD_FM_D2R, "5Cxx: Set decay 2 of operator 1 (0 to 1F)", constVal<0>, effectValAnd<31>}}, + {0x5d, {DIV_CMD_FM_D2R, "5Dxx: Set decay 2 of operator 2 (0 to 1F)", constVal<1>, effectValAnd<31>}}, + {0x5e, {DIV_CMD_FM_D2R, "5Exx: Set decay 2 of operator 3 (0 to 1F)", constVal<2>, effectValAnd<31>}}, + {0x5f, {DIV_CMD_FM_D2R, "5Fxx: Set decay 2 of operator 4 (0 to 1F)", constVal<3>, effectValAnd<31>}}, }; - auto c64PostEffectHandler=[this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x10: // select waveform - dispatchCmd(DivCommand(DIV_CMD_WAVE,ch,effectVal)); - break; - case 0x11: // cutoff - dispatchCmd(DivCommand(DIV_CMD_C64_CUTOFF,ch,effectVal)); - break; - case 0x12: // duty - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); - break; - case 0x13: // resonance - dispatchCmd(DivCommand(DIV_CMD_C64_RESONANCE,ch,effectVal)); - break; - case 0x14: // filter mode - dispatchCmd(DivCommand(DIV_CMD_C64_FILTER_MODE,ch,effectVal)); - break; - case 0x15: // reset time - dispatchCmd(DivCommand(DIV_CMD_C64_RESET_TIME,ch,effectVal)); - break; - case 0x1a: // reset mask - dispatchCmd(DivCommand(DIV_CMD_C64_RESET_MASK,ch,effectVal)); - break; - case 0x1b: // cutoff reset - dispatchCmd(DivCommand(DIV_CMD_C64_FILTER_RESET,ch,effectVal)); - break; - case 0x1c: // duty reset - dispatchCmd(DivCommand(DIV_CMD_C64_DUTY_RESET,ch,effectVal)); - break; - case 0x1e: // extended - dispatchCmd(DivCommand(DIV_CMD_C64_EXTENDED,ch,effectVal)); - break; - case 0x30: case 0x31: case 0x32: case 0x33: - case 0x34: case 0x35: case 0x36: case 0x37: - case 0x38: case 0x39: case 0x3a: case 0x3b: - case 0x3c: case 0x3d: case 0x3e: case 0x3f: // fine duty - dispatchCmd(DivCommand(DIV_CMD_C64_FINE_DUTY,ch,((effect&0x0f)<<8)|effectVal)); - break; - case 0x40: case 0x41: case 0x42: case 0x43: - case 0x44: case 0x45: case 0x46: case 0x47: // fine cutoff - dispatchCmd(DivCommand(DIV_CMD_C64_FINE_CUTOFF,ch,((effect&0x07)<<8)|effectVal)); - break; - default: - return false; - } - return true; + EffectHandlerMap fmOPMPostEffectHandlerMap(fmOPNPostEffectHandlerMap); + fmOPMPostEffectHandlerMap.insert({ + {0x10, {DIV_CMD_STD_NOISE_FREQ, "10xx: Set noise frequency (xx: value; 0 disables noise)"}}, + {0x17, {DIV_CMD_FM_LFO, "17xx: Set LFO speed"}}, + {0x18, {DIV_CMD_FM_LFO_WAVE, "18xx: Set LFO waveform (0 saw, 1 square, 2 triangle, 3 noise)"}}, + {0x1e, {DIV_CMD_FM_AM_DEPTH, "1Exx: Set AM depth (0 to 7F)", effectValAnd<127>}}, + {0x1f, {DIV_CMD_FM_PM_DEPTH, "1Fxx: Set PM depth (0 to 7F)", effectValAnd<127>}}, + {0x55, {DIV_CMD_FM_SSG, "55xy: Set detune 2 (x: operator from 1 to 4 (0 for all ops); y: detune from 0 to 3)", effectOpVal<4>, effectValAnd<3>}}, + }); + + EffectHandlerMap fmOPZPostEffectHandlerMap(fmOPMPostEffectHandlerMap); + fmOPZPostEffectHandlerMap.insert({ + {0x28, {DIV_CMD_FM_REV, "28xy: Set reverb (x: operator from 1 to 4 (0 for all ops); y: reverb from 0 to 7)", effectOpVal<4>, effectValAnd<7>}}, + {0x2a, {DIV_CMD_FM_WS, "2Axy: Set waveform (x: operator from 1 to 4 (0 for all ops); y: waveform from 0 to 7)", effectOpVal<4>, effectValAnd<7>}}, + {0x2b, {DIV_CMD_FM_EG_SHIFT, "2Bxy: Set envelope generator shift (x: operator from 1 to 4 (0 for all ops); y: shift from 0 to 3)", effectOpVal<4>, effectValAnd<3>}}, + {0x2c, {DIV_CMD_FM_FINE, "2Cxy: Set fine multiplier (x: operator from 1 to 4 (0 for all ops); y: fine)", effectOpVal<4>, effectValAnd<15>}}, + }); + const EffectHandler fmOPZFixFreqHandler[4]={ + {DIV_CMD_FM_FIXFREQ, "3xyy: Set fixed frequency of operator 1 (x: octave from 0 to 7; y: frequency)", constVal<0>, effectValLong<11>}, + {DIV_CMD_FM_FIXFREQ, "3xyy: Set fixed frequency of operator 2 (x: octave from 8 to F; y: frequency)", constVal<1>, effectValLong<11>}, + {DIV_CMD_FM_FIXFREQ, "4xyy: Set fixed frequency of operator 3 (x: octave from 0 to 7; y: frequency)", constVal<2>, effectValLong<11>}, + {DIV_CMD_FM_FIXFREQ, "4xyy: Set fixed frequency of operator 4 (x: octave from 8 to F; y: frequency)", constVal<3>, effectValLong<11>}, + }; + for (int i=0; i<32; i++) { + fmOPZPostEffectHandlerMap.emplace(0x30+i,fmOPZFixFreqHandler[i/8]); + } + + fmOPNPostEffectHandlerMap.insert({ + {0x10, {DIV_CMD_FM_LFO, "10xy: Setup LFO (x: enable; y: speed)"}}, + {0x18, {DIV_CMD_FM_EXTCH, "18xx: Toggle extended channel 3 mode"}}, + {0x55, {DIV_CMD_FM_SSG, "55xy: Set SSG envelope (x: operator from 1 to 4 (0 for all ops); y: 0-7 on, 8 off)", effectOpVal<4>, effectValAnd<15>}}, + }); + EffectHandlerMap fmOPN2PostEffectHandlerMap(fmOPNPostEffectHandlerMap); + + fmOPNPostEffectHandlerMap.insert(ayPostEffectHandlerMap.begin(), ayPostEffectHandlerMap.end()); + + EffectHandlerMap fmOPLLPostEffectHandlerMap={ + {0x11, {DIV_CMD_FM_FB, "11xx: Set feedback (0 to 7)"}}, + {0x12, {DIV_CMD_FM_TL, "12xx: Set level of operator 1 (0 highest, 3F lowest)", constVal<0>, effectVal}}, + {0x13, {DIV_CMD_FM_TL, "13xx: Set level of operator 2 (0 highest, 3F lowest)", constVal<1>, effectVal}}, + {0x16, {DIV_CMD_FM_MULT, "16xy: Set operator multiplier (x: operator from 1 to 2; y: multiplier)", effectOpValNoZero<2>, effectValAnd<15>}}, + {0x19, {DIV_CMD_FM_AR, "19xx: Set attack of all operators (0 to F)", constVal<-1>, effectValAnd<15>}}, + {0x1a, {DIV_CMD_FM_AR, "1Axx: Set attack of operator 1 (0 to F)", constVal<0>, effectValAnd<15>}}, + {0x1b, {DIV_CMD_FM_AR, "1Bxx: Set attack of operator 2 (0 to F)", constVal<1>, effectValAnd<15>}}, + {0x50, {DIV_CMD_FM_AM, "50xy: Set AM (x: operator from 1 to 2 (0 for all ops); y: AM)", effectOpVal<2>, effectValAnd<1>}}, + {0x51, {DIV_CMD_FM_SL, "51xy: Set sustain level (x: operator from 1 to 2 (0 for all ops); y: sustain)", effectOpVal<2>, effectValAnd<15>}}, + {0x52, {DIV_CMD_FM_RR, "52xy: Set release (x: operator from 1 to 2 (0 for all ops); y: release)", effectOpVal<2>, effectValAnd<15>}}, + {0x53, {DIV_CMD_FM_VIB, "53xy: Set vibrato (x: operator from 1 to 2 (0 for all ops); y: enabled)", effectOpVal<2>, effectValAnd<1>}}, + {0x54, {DIV_CMD_FM_RS, "54xy: Set envelope scale (x: operator from 1 to 2 (0 for all ops); y: scale from 0 to 3)", effectOpVal<2>, effectValAnd<3>}}, + {0x55, {DIV_CMD_FM_SUS, "55xy: Set envelope sustain (x: operator from 1 to 2 (0 for all ops); y: enabled)", effectOpVal<2>, effectValAnd<1>}}, + {0x56, {DIV_CMD_FM_DR, "56xx: Set decay of all operators (0 to F)", constVal<-1>, effectValAnd<15>}}, + {0x57, {DIV_CMD_FM_DR, "57xx: Set decay of operator 1 (0 to F)", constVal<0>, effectValAnd<15>}}, + {0x58, {DIV_CMD_FM_DR, "58xx: Set decay of operator 2 (0 to F)", constVal<1>, effectValAnd<15>}}, + {0x5b, {DIV_CMD_FM_KSR, "5Bxy: Set whether key will scale envelope (x: operator from 1 to 2 (0 for all ops); y: enabled)", effectOpVal<2>, effectValAnd<1>}}, }; - auto ayPostEffectHandler=[this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x12: // duty on 8930 - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,0x10+(effectVal&15))); - break; - case 0x20: // mode - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal&15)); - break; - case 0x21: // noise freq - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_FREQ,ch,effectVal)); - break; - case 0x22: // envelope enable - dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_SET,ch,effectVal)); - break; - case 0x23: // envelope period low - dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_LOW,ch,effectVal)); - break; - case 0x24: // envelope period high - dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_HIGH,ch,effectVal)); - break; - case 0x25: // envelope slide up - dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_SLIDE,ch,-effectVal)); - break; - case 0x26: // envelope slide down - dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_SLIDE,ch,effectVal)); - break; - case 0x27: // noise and mask - dispatchCmd(DivCommand(DIV_CMD_AY_NOISE_MASK_AND,ch,effectVal)); - break; - case 0x28: // noise or mask - dispatchCmd(DivCommand(DIV_CMD_AY_NOISE_MASK_OR,ch,effectVal)); - break; - case 0x29: // auto-envelope - dispatchCmd(DivCommand(DIV_CMD_AY_AUTO_ENVELOPE,ch,effectVal)); - break; - case 0x2d: // TEST - dispatchCmd(DivCommand(DIV_CMD_AY_IO_WRITE,ch,255,effectVal)); - break; - case 0x2e: // I/O port A - dispatchCmd(DivCommand(DIV_CMD_AY_IO_WRITE,ch,0,effectVal)); - break; - case 0x2f: // I/O port B - dispatchCmd(DivCommand(DIV_CMD_AY_IO_WRITE,ch,1,effectVal)); - break; - default: - return false; - } - return true; + EffectHandlerMap fmOPLPostEffectHandlerMap={ + {0x10, {DIV_CMD_FM_LFO, "10xx: Set global AM depth (0: 1dB, 1: 4.8dB)", effectValAnd<1>}}, + {0x11, {DIV_CMD_FM_FB, "11xx: Set feedback (0 to 7)"}}, + {0x12, {DIV_CMD_FM_TL, "12xx: Set level of operator 1 (0 highest, 3F lowest)", constVal<0>, effectVal}}, + {0x13, {DIV_CMD_FM_TL, "13xx: Set level of operator 2 (0 highest, 3F lowest)", constVal<1>, effectVal}}, + {0x14, {DIV_CMD_FM_TL, "14xx: Set level of operator 3 (0 highest, 3F lowest)", constVal<2>, effectVal}}, + {0x15, {DIV_CMD_FM_TL, "15xx: Set level of operator 4 (0 highest, 3F lowest)", constVal<3>, effectVal}}, + {0x16, {DIV_CMD_FM_MULT, "16xy: Set operator multiplier (x: operator from 1 to 4; y: multiplier)", effectOpValNoZero<4>, effectValAnd<15>}}, + {0x17, {DIV_CMD_FM_LFO, "17xx: Set global vibrato depth (0: normal, 1: double)", [](unsigned char, unsigned char val) -> int { return (val&1)+2; }}}, + {0x19, {DIV_CMD_FM_AR, "19xx: Set attack of all operators (0 to F)", constVal<-1>, effectValAnd<15>}}, + {0x1a, {DIV_CMD_FM_AR, "1Axx: Set attack of operator 1 (0 to F)", constVal<0>, effectValAnd<15>}}, + {0x1b, {DIV_CMD_FM_AR, "1Bxx: Set attack of operator 2 (0 to F)", constVal<1>, effectValAnd<15>}}, + {0x1c, {DIV_CMD_FM_AR, "1Cxx: Set attack of operator 3 (0 to F)", constVal<2>, effectValAnd<15>}}, + {0x1d, {DIV_CMD_FM_AR, "1Dxx: Set attack of operator 4 (0 to F)", constVal<3>, effectValAnd<15>}}, + {0x2a, {DIV_CMD_FM_WS, "2Axy: Set waveform (x: operator from 1 to 4 (0 for all ops); y: waveform from 0 to 3 in OPL2 and 0 to 7 in OPL3)", effectOpVal<4>, effectValAnd<7>}}, + {0x50, {DIV_CMD_FM_AM, "50xy: Set AM (x: operator from 1 to 4 (0 for all ops); y: AM)", effectOpVal<4>, effectValAnd<1>}}, + {0x51, {DIV_CMD_FM_SL, "51xy: Set sustain level (x: operator from 1 to 4 (0 for all ops); y: sustain)", effectOpVal<4>, effectValAnd<15>}}, + {0x52, {DIV_CMD_FM_RR, "52xy: Set release (x: operator from 1 to 4 (0 for all ops); y: release)", effectOpVal<4>, effectValAnd<15>}}, + {0x53, {DIV_CMD_FM_VIB, "53xy: Set vibrato (x: operator from 1 to 4 (0 for all ops); y: enabled)", effectOpVal<4>, effectValAnd<1>}}, + {0x54, {DIV_CMD_FM_RS, "54xy: Set envelope scale (x: operator from 1 to 4 (0 for all ops); y: scale from 0 to 3)", effectOpVal<4>, effectValAnd<3>}}, + {0x55, {DIV_CMD_FM_SUS, "55xy: Set envelope sustain (x: operator from 1 to 4 (0 for all ops); y: enabled)", effectOpVal<4>, effectValAnd<1>}}, + {0x56, {DIV_CMD_FM_DR, "56xx: Set decay of all operators (0 to F)", constVal<-1>, effectValAnd<15>}}, + {0x57, {DIV_CMD_FM_DR, "57xx: Set decay of operator 1 (0 to F)", constVal<0>, effectValAnd<15>}}, + {0x58, {DIV_CMD_FM_DR, "58xx: Set decay of operator 2 (0 to F)", constVal<1>, effectValAnd<15>}}, + {0x59, {DIV_CMD_FM_DR, "59xx: Set decay of operator 3 (0 to F)", constVal<2>, effectValAnd<15>}}, + {0x5a, {DIV_CMD_FM_DR, "5Axx: Set decay of operator 4 (0 to F)", constVal<3>, effectValAnd<15>}}, + {0x5b, {DIV_CMD_FM_KSR, "5Bxy: Set whether key will scale envelope (x: operator from 1 to 4 (0 for all ops); y: enabled)", effectOpVal<4>, effectValAnd<1>}}, }; - auto segaPCMPostEffectHandler=[this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x20: // PCM frequency - dispatchCmd(DivCommand(DIV_CMD_SAMPLE_FREQ,ch,effectVal)); - break; - default: - return false; - } - return true; + EffectHandlerMap c64PostEffectHandlerMap={ + {0x10, {DIV_CMD_WAVE, "10xx: Set waveform (bit 0: triangle; bit 1: saw; bit 2: pulse; bit 3: noise)"}}, + {0x11, {DIV_CMD_C64_CUTOFF, "11xx: Set coarse cutoff (not recommended; use 4xxx instead)"}}, + {0x12, {DIV_CMD_STD_NOISE_MODE, "12xx: Set coarse pulse width (not recommended; use 3xxx instead)"}}, + {0x13, {DIV_CMD_C64_RESONANCE, "13xx: Set resonance (0 to F)"}}, + {0x14, {DIV_CMD_C64_FILTER_MODE, "14xx: Set filter mode (bit 0: low pass; bit 1: band pass; bit 2: high pass)"}}, + {0x15, {DIV_CMD_C64_RESET_TIME, "15xx: Set envelope reset time"}}, + {0x1a, {DIV_CMD_C64_RESET_MASK, "1Axx: Disable envelope reset for this channel (1 disables; 0 enables)"}}, + {0x1b, {DIV_CMD_C64_FILTER_RESET, "1Bxy: Reset cutoff (x: on new note; y: now)"}}, + {0x1c, {DIV_CMD_C64_DUTY_RESET, "1Cxy: Reset pulse width (x: on new note; y: now)"}}, + {0x1e, {DIV_CMD_C64_EXTENDED, "1Exy: Change additional parameters"}}, }; + const EffectHandler c64FineDutyHandler(DIV_CMD_C64_FINE_DUTY, "3xxx: Set pulse width (0 to FFF)", effectValLong<12>); + const EffectHandler c64FineCutoffHandler(DIV_CMD_C64_FINE_CUTOFF, "4xxx: Set cutoff (0 to 7FF)", effectValLong<11>); + for (int i=0; i<16; i++) c64PostEffectHandlerMap.emplace(0x30+i,c64FineDutyHandler); + for (int i=0; i<8; i++) c64PostEffectHandlerMap.emplace(0x40+i,c64FineCutoffHandler); + + EffectHandlerMap waveOnlyEffectHandlerMap={ + {0x10, {DIV_CMD_WAVE, "10xx: Set waveform"}}, + }; + + EffectHandlerMap segaPCMPostEffectHandlerMap={ + {0x20, {DIV_CMD_SAMPLE_FREQ, "20xx: Set PCM frequency"}} + }; + + // SysDefs sysDefs[DIV_SYSTEM_YMU759]=new DivSysDef( "Yamaha YMU759 (MA-2)", NULL, 0x01, 0x01, 17, true, false, 0, false, @@ -774,15 +606,8 @@ void DivEngine::registerSystems() { {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; + { + {0x20, {DIV_CMD_STD_NOISE_MODE, "20xy: Set noise mode (x: preset freq/ch3 freq; y: thin pulse/noise)"}} } ); @@ -800,24 +625,12 @@ void DivEngine::registerSystems() { {DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_WAVE, DIV_CH_NOISE}, {DIV_INS_GB, DIV_INS_GB, DIV_INS_GB, DIV_INS_GB}, {}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x10: // select waveform - dispatchCmd(DivCommand(DIV_CMD_WAVE,ch,effectVal)); - break; - case 0x11: case 0x12: // duty or noise mode - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); - break; - case 0x13: // sweep params - dispatchCmd(DivCommand(DIV_CMD_GB_SWEEP_TIME,ch,effectVal)); - break; - case 0x14: // sweep direction - dispatchCmd(DivCommand(DIV_CMD_GB_SWEEP_DIR,ch,effectVal)); - break; - default: - return false; - } - return true; + { + {0x10, {DIV_CMD_WAVE, "10xx: Set waveform"}}, + {0x11, {DIV_CMD_STD_NOISE_MODE, "11xx: Set noise length (0: long; 1: short)"}}, + {0x12, {DIV_CMD_STD_NOISE_MODE, "12xx: Set duty cycle (0 to 3)"}}, + {0x13, {DIV_CMD_GB_SWEEP_TIME, "13xy: Setup sweep (x: time; y: shift)"}}, + {0x14, {DIV_CMD_GB_SWEEP_DIR, "14xx: Set sweep direction (0: up; 1: down)"}} } ); @@ -829,27 +642,12 @@ void DivEngine::registerSystems() { {DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE}, {DIV_INS_PCE, DIV_INS_PCE, DIV_INS_PCE, DIV_INS_PCE, DIV_INS_PCE, DIV_INS_PCE}, {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x10: // select waveform - dispatchCmd(DivCommand(DIV_CMD_WAVE,ch,effectVal)); - break; - case 0x11: // noise mode - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); - break; - case 0x12: // LFO mode - dispatchCmd(DivCommand(DIV_CMD_PCE_LFO_MODE,ch,effectVal)); - break; - case 0x13: // LFO speed - dispatchCmd(DivCommand(DIV_CMD_PCE_LFO_SPEED,ch,effectVal)); - break; - case 0x17: // PCM enable - dispatchCmd(DivCommand(DIV_CMD_SAMPLE_MODE,ch,(effectVal>0))); - break; - default: - return false; - } - return true; + { + {0x10, {DIV_CMD_WAVE, "10xx: Set waveform"}}, + {0x11, {DIV_CMD_STD_NOISE_MODE, "11xx: Toggle noise mode"}}, + {0x12, {DIV_CMD_PCE_LFO_MODE, "12xx: Setup LFO (0: disabled; 1: 1x depth; 2: 16x depth; 3: 256x depth)"}}, + {0x13, {DIV_CMD_PCE_LFO_SPEED, "13xx: Set LFO speed"}}, + {0x17, {DIV_CMD_SAMPLE_MODE, "17xx: Toggle PCM mode"}} } ); @@ -861,27 +659,12 @@ void DivEngine::registerSystems() { {DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_WAVE, DIV_CH_NOISE, DIV_CH_PCM}, {DIV_INS_STD, DIV_INS_STD, DIV_INS_STD, DIV_INS_STD, DIV_INS_AMIGA}, {}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x11: // DMC write - dispatchCmd(DivCommand(DIV_CMD_NES_DMC,ch,effectVal)); - break; - case 0x12: // duty or noise mode - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); - break; - case 0x13: // sweep up - dispatchCmd(DivCommand(DIV_CMD_NES_SWEEP,ch,0,effectVal)); - break; - case 0x14: // sweep down - dispatchCmd(DivCommand(DIV_CMD_NES_SWEEP,ch,1,effectVal)); - break; - case 0x18: // DPCM mode - dispatchCmd(DivCommand(DIV_CMD_SAMPLE_MODE,ch,effectVal)); - break; - default: - return false; - } - return true; + { + {0x11, {DIV_CMD_NES_DMC, "11xx: Write to delta modulation counter (0 to 7F)"}}, + {0x12, {DIV_CMD_STD_NOISE_MODE, "12xx: Set duty cycle/noise mode (pulse: 0 to 3; noise: 0 or 1)"}}, + {0x13, {DIV_CMD_NES_SWEEP, "13xy: Sweep up (x: time; y: shift)",constVal<0>,effectVal}}, + {0x14, {DIV_CMD_NES_SWEEP, "14xy: Sweep down (x: time; y: shift)",constVal<1>,effectVal}}, + {0x18, {DIV_CMD_SAMPLE_MODE, "18xx: Select PCM/DPCM mode (0: PCM; 1: DPCM)"}} } ); @@ -905,8 +688,8 @@ void DivEngine::registerSystems() { {DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE}, {DIV_INS_C64, DIV_INS_C64, DIV_INS_C64}, {}, - [](int,unsigned char,unsigned char) -> bool {return false;}, - c64PostEffectHandler + {}, + c64PostEffectHandlerMap ); sysDefs[DIV_SYSTEM_C64_8580]=new DivSysDef( @@ -917,8 +700,8 @@ void DivEngine::registerSystems() { {DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE}, {DIV_INS_C64, DIV_INS_C64, DIV_INS_C64}, {}, - [](int,unsigned char,unsigned char) -> bool {return false;}, - c64PostEffectHandler + {}, + c64PostEffectHandlerMap ); sysDefs[DIV_SYSTEM_ARCADE]=new DivSysDef( @@ -927,17 +710,6 @@ void DivEngine::registerSystems() { {}, {}, {}, {} ); - auto fmHardResetEffectHandler=[this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x30: // toggle hard-reset - dispatchCmd(DivCommand(DIV_CMD_FM_HARD_RESET,ch,effectVal)); - break; - default: - return false; - } - return true; - }; - sysDefs[DIV_SYSTEM_YM2610]=new DivSysDef( "Neo Geo CD", NULL, 0x09, 0x09, 13, true, true, 0x151, false, "like Neo Geo, but lacking the ADPCM-B channel since they couldn't connect the pins.", @@ -946,8 +718,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM}, {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, {}, - fmHardResetEffectHandler, - fmPostEffectHandler + fmEffectHandlerMap, + fmOPNPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_YM2610_EXT]=new DivSysDef( @@ -958,8 +730,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM}, {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, {}, - fmHardResetEffectHandler, - fmPostEffectHandler + fmEffectHandlerMap, + fmOPNPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_AY8910]=new DivSysDef( @@ -970,8 +742,8 @@ void DivEngine::registerSystems() { {DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE}, {DIV_INS_AY, DIV_INS_AY, DIV_INS_AY}, {}, - [](int,unsigned char,unsigned char) -> bool {return false;}, - ayPostEffectHandler + {}, + ayPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_AMIGA]=new DivSysDef( @@ -982,22 +754,11 @@ void DivEngine::registerSystems() { {DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM}, {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, {}, - [](int,unsigned char,unsigned char) -> bool {return false;}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x10: // toggle filter - dispatchCmd(DivCommand(DIV_CMD_AMIGA_FILTER,ch,effectVal)); - break; - case 0x11: // toggle AM - dispatchCmd(DivCommand(DIV_CMD_AMIGA_AM,ch,effectVal)); - break; - case 0x12: // toggle PM - dispatchCmd(DivCommand(DIV_CMD_AMIGA_PM,ch,effectVal)); - break; - default: - return false; - } - return true; + {}, + { + {0x10, {DIV_CMD_AMIGA_FILTER, "10xx: Toggle filter (0 disables; 1 enables)"}}, + {0x11, {DIV_CMD_AMIGA_AM, "11xx: Toggle AM with next channel"}}, + {0x12, {DIV_CMD_AMIGA_PM, "12xx: Toggle period modulation with next channel"}}, } ); @@ -1009,24 +770,10 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM}, {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM}, {}, - fmHardResetEffectHandler, - fmPostEffectHandler + fmEffectHandlerMap, + fmOPMPostEffectHandlerMap ); - auto opn2EffectHandler=[this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x17: // DAC enable - dispatchCmd(DivCommand(DIV_CMD_SAMPLE_MODE,ch,(effectVal>0))); - break; - case 0x30: // toggle hard-reset - dispatchCmd(DivCommand(DIV_CMD_FM_HARD_RESET,ch,effectVal)); - break; - default: - return false; - } - return true; - }; - sysDefs[DIV_SYSTEM_YM2612]=new DivSysDef( "Yamaha YM2612 (OPN2)", NULL, 0x83, 0, 6, true, false, 0x150, false, "this chip is mostly known for being in the Sega Genesis (but it also was on the FM Towns computer).", @@ -1035,8 +782,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM}, {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM}, {DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_AMIGA}, - opn2EffectHandler, - fmPostEffectHandler + fmOPN2EffectHandlerMap, + fmOPN2PostEffectHandlerMap ); sysDefs[DIV_SYSTEM_TIA]=new DivSysDef( @@ -1047,17 +794,8 @@ void DivEngine::registerSystems() { {DIV_CH_WAVE, DIV_CH_WAVE}, {DIV_INS_TIA, DIV_INS_TIA}, {}, - [](int,unsigned char,unsigned char) -> bool {return false;}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x10: // select waveform - dispatchCmd(DivCommand(DIV_CMD_WAVE,ch,effectVal)); - break; - default: - return false; - } - return true; - } + {}, + waveOnlyEffectHandlerMap ); sysDefs[DIV_SYSTEM_SAA1099]=new DivSysDef( @@ -1068,22 +806,11 @@ void DivEngine::registerSystems() { {DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE}, {DIV_INS_SAA1099, DIV_INS_SAA1099, DIV_INS_SAA1099, DIV_INS_SAA1099, DIV_INS_SAA1099, DIV_INS_SAA1099}, {}, - [](int,unsigned char,unsigned char) -> bool {return false;}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x10: // select channel mode - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); - break; - case 0x11: // set noise freq - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_FREQ,ch,effectVal)); - break; - case 0x12: // setup envelope - dispatchCmd(DivCommand(DIV_CMD_SAA_ENVELOPE,ch,effectVal)); - break; - default: - return false; - } - return true; + {}, + { + {0x10, {DIV_CMD_STD_NOISE_MODE, "10xy: Set channel mode (x: noise; y: tone)"}}, + {0x11, {DIV_CMD_STD_NOISE_FREQ, "11xx: Set noise frequency"}}, + {0x12, {DIV_CMD_SAA_ENVELOPE, "12xx: Setup envelope (refer to docs for more information)"}}, } ); @@ -1095,21 +822,10 @@ void DivEngine::registerSystems() { {DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE}, {DIV_INS_AY8930, DIV_INS_AY8930, DIV_INS_AY8930}, {}, - [](int,unsigned char,unsigned char) -> bool {return false;}, - ayPostEffectHandler + {}, + ay8930PostEffectHandlerMap ); - auto waveOnlyEffectHandler=[this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x10: // select waveform - dispatchCmd(DivCommand(DIV_CMD_WAVE,ch,effectVal)); - break; - default: - return false; - } - return true; - }; - sysDefs[DIV_SYSTEM_VIC20]=new DivSysDef( "Commodore VIC-20", NULL, 0x85, 0, 4, false, true, 0, false, "Commodore's successor to the PET.\nits square wave channels are more than just square...", @@ -1118,7 +834,7 @@ void DivEngine::registerSystems() { {DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_NOISE}, {DIV_INS_VIC, DIV_INS_VIC, DIV_INS_VIC, DIV_INS_VIC}, {}, - waveOnlyEffectHandler + waveOnlyEffectHandlerMap ); sysDefs[DIV_SYSTEM_PET]=new DivSysDef( @@ -1129,7 +845,7 @@ void DivEngine::registerSystems() { {DIV_CH_PULSE}, {DIV_INS_PET}, {}, - waveOnlyEffectHandler + waveOnlyEffectHandlerMap ); sysDefs[DIV_SYSTEM_SNES]=new DivSysDef( @@ -1149,32 +865,12 @@ void DivEngine::registerSystems() { {DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_WAVE}, {DIV_INS_VRC6, DIV_INS_VRC6, DIV_INS_VRC6_SAW}, {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_NULL}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x12: // duty or noise mode - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); - break; - case 0x17: // PCM enable - dispatchCmd(DivCommand(DIV_CMD_SAMPLE_MODE,ch,(effectVal>0))); - break; - default: - return false; - } - return true; + { + {0x12, {DIV_CMD_STD_NOISE_MODE, "12xx: Set duty cycle (pulse: 0 to 7)"}}, + {0x17, {DIV_CMD_SAMPLE_MODE, "17xx: Toggle PCM mode (pulse channel)"}}, } ); - auto oplEffectHandler=[this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x30: // toggle hard-reset - dispatchCmd(DivCommand(DIV_CMD_FM_HARD_RESET,ch,effectVal)); - break; - default: - return false; - } - return true; - }; - sysDefs[DIV_SYSTEM_OPLL]=new DivSysDef( "Yamaha YM2413 (OPLL)", NULL, 0x89, 0, 9, true, false, 0x150, false, "cost-reduced version of the OPL with 16 patches and only one of them is user-configurable.", @@ -1183,8 +879,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM}, {DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL}, {}, - oplEffectHandler, - fmOPLLPostEffectHandler + fmEffectHandlerMap, + fmOPLLPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_FDS]=new DivSysDef( @@ -1195,30 +891,13 @@ void DivEngine::registerSystems() { {DIV_CH_WAVE}, {DIV_INS_FDS}, {}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x10: // select waveform - dispatchCmd(DivCommand(DIV_CMD_WAVE,ch,effectVal)); - break; - case 0x11: // modulation depth - dispatchCmd(DivCommand(DIV_CMD_FDS_MOD_DEPTH,ch,effectVal)); - break; - case 0x12: // modulation enable/high - dispatchCmd(DivCommand(DIV_CMD_FDS_MOD_HIGH,ch,effectVal)); - break; - case 0x13: // modulation low - dispatchCmd(DivCommand(DIV_CMD_FDS_MOD_LOW,ch,effectVal)); - break; - case 0x14: // modulation pos - dispatchCmd(DivCommand(DIV_CMD_FDS_MOD_POS,ch,effectVal)); - break; - case 0x15: // modulation wave - dispatchCmd(DivCommand(DIV_CMD_FDS_MOD_WAVE,ch,effectVal)); - break; - default: - return false; - } - return true; + { + {0x10, {DIV_CMD_WAVE, "10xx: Set waveform"}}, + {0x11, {DIV_CMD_FDS_MOD_DEPTH, "11xx: Set modulation depth"}}, + {0x12, {DIV_CMD_FDS_MOD_HIGH, "12xy: Set modulation speed high byte (x: enable; y: value)"}}, + {0x13, {DIV_CMD_FDS_MOD_LOW, "13xx: Set modulation speed low byte"}}, + {0x14, {DIV_CMD_FDS_MOD_POS, "14xx: Set modulator position"}}, + {0x15, {DIV_CMD_FDS_MOD_WAVE, "15xx: Set modulator table to waveform"}}, } ); @@ -1230,18 +909,8 @@ void DivEngine::registerSystems() { {DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PCM}, {DIV_INS_STD, DIV_INS_STD, DIV_INS_AMIGA}, {}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x11: // DMC write - dispatchCmd(DivCommand(DIV_CMD_NES_DMC,ch,effectVal)); - break; - case 0x12: // duty or noise mode - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); - break; - default: - return false; - } - return true; + { + {0x12, {DIV_CMD_STD_NOISE_MODE, "12xx: Set duty cycle/noise mode (pulse: 0 to 3; noise: 0 or 1)"}}, } ); @@ -1253,51 +922,20 @@ void DivEngine::registerSystems() { {DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE}, {DIV_INS_N163, DIV_INS_N163, DIV_INS_N163, DIV_INS_N163, DIV_INS_N163, DIV_INS_N163, DIV_INS_N163, DIV_INS_N163}, {}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x10: // select instrument waveform - dispatchCmd(DivCommand(DIV_CMD_WAVE,ch,effectVal)); - break; - case 0x11: // select instrument waveform position in RAM - dispatchCmd(DivCommand(DIV_CMD_N163_WAVE_POSITION,ch,effectVal)); - break; - case 0x12: // select instrument waveform length in RAM - dispatchCmd(DivCommand(DIV_CMD_N163_WAVE_LENGTH,ch,effectVal)); - break; - case 0x13: // change instrument waveform update mode - dispatchCmd(DivCommand(DIV_CMD_N163_WAVE_MODE,ch,effectVal)); - break; - case 0x14: // select waveform for load to RAM - dispatchCmd(DivCommand(DIV_CMD_N163_WAVE_LOAD,ch,effectVal)); - break; - case 0x15: // select waveform position for load to RAM - dispatchCmd(DivCommand(DIV_CMD_N163_WAVE_LOADPOS,ch,effectVal)); - break; - case 0x16: // select waveform length for load to RAM - dispatchCmd(DivCommand(DIV_CMD_N163_WAVE_LOADLEN,ch,effectVal)); - break; - case 0x17: // change waveform load mode - dispatchCmd(DivCommand(DIV_CMD_N163_WAVE_LOADMODE,ch,effectVal)); - break; - case 0x18: // change channel limits - dispatchCmd(DivCommand(DIV_CMD_N163_CHANNEL_LIMIT,ch,effectVal)); - break; - case 0x20: // (global) select waveform for load to RAM - dispatchCmd(DivCommand(DIV_CMD_N163_GLOBAL_WAVE_LOAD,ch,effectVal)); - break; - case 0x21: // (global) select waveform position for load to RAM - dispatchCmd(DivCommand(DIV_CMD_N163_GLOBAL_WAVE_LOADPOS,ch,effectVal)); - break; - case 0x22: // (global) select waveform length for load to RAM - dispatchCmd(DivCommand(DIV_CMD_N163_GLOBAL_WAVE_LOADLEN,ch,effectVal)); - break; - case 0x23: // (global) change waveform load mode - dispatchCmd(DivCommand(DIV_CMD_N163_GLOBAL_WAVE_LOADMODE,ch,effectVal)); - break; - default: - return false; - } - return true; + { + {0x10, {DIV_CMD_WAVE, "10xx: Select waveform"}}, + {0x11, {DIV_CMD_N163_WAVE_POSITION, "11xx: Set waveform position in RAM (single nibble unit)"}}, + {0x12, {DIV_CMD_N163_WAVE_LENGTH, "12xx: Set waveform length in RAM (04 to FC, 4 nibble unit)"}}, + {0x13, {DIV_CMD_N163_WAVE_MODE, "130x: Change waveform update mode (0: off; bit 0: update now; bit 1: update when every waveform changes)"}}, + {0x14, {DIV_CMD_N163_WAVE_LOAD, "14xx: Select waveform for load to RAM"}}, + {0x15, {DIV_CMD_N163_WAVE_LOADPOS, "15xx: Set waveform position for load to RAM (single nibble unit)"}}, + {0x16, {DIV_CMD_N163_WAVE_LOADLEN, "16xx: Set waveform length for load to RAM (04 to FC, 4 nibble unit)"}}, + {0x17, {DIV_CMD_N163_WAVE_LOADMODE, "170x: Change waveform load mode (0: off; bit 0: load now; bit 1: load when every waveform changes)"}}, + {0x18, {DIV_CMD_N163_CHANNEL_LIMIT, "180x: Change channel limits (0 to 7, x + 1)"}}, + {0x20, {DIV_CMD_N163_GLOBAL_WAVE_LOAD, "20xx: (Global) Select waveform for load to RAM"}}, + {0x21, {DIV_CMD_N163_GLOBAL_WAVE_LOADPOS, "21xx: (Global) Set waveform position for load to RAM (single nibble unit)"}}, + {0x22, {DIV_CMD_N163_GLOBAL_WAVE_LOADLEN, "22xx: (Global) Set waveform length for load to RAM (04 to FC, 4 nibble unit)"}}, + {0x23, {DIV_CMD_N163_GLOBAL_WAVE_LOADMODE, "230x: (Global) Change waveform load mode (0: off; bit 0: load now; bit 1: load when every waveform changes)"}}, } ); @@ -1309,8 +947,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE}, {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY}, {}, - fmHardResetEffectHandler, - fmPostEffectHandler + fmEffectHandlerMap, + fmOPNPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_OPN_EXT]=new DivSysDef( @@ -1321,8 +959,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE}, {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY}, {}, - fmHardResetEffectHandler, - fmPostEffectHandler + fmEffectHandlerMap, + fmOPNPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_PC98]=new DivSysDef( @@ -1333,8 +971,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_PCM}, {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_AMIGA}, {}, - fmHardResetEffectHandler, - fmPostEffectHandler + fmEffectHandlerMap, + fmOPNPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_PC98_EXT]=new DivSysDef( @@ -1345,8 +983,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_PCM}, {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_AMIGA}, {}, - fmHardResetEffectHandler, - fmPostEffectHandler + fmEffectHandlerMap, + fmOPNPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_OPL]=new DivSysDef( @@ -1357,8 +995,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM}, {DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL}, {}, - oplEffectHandler, - fmOPLPostEffectHandler + fmEffectHandlerMap, + fmOPLPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_OPL2]=new DivSysDef( @@ -1369,8 +1007,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM}, {DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL}, {}, - oplEffectHandler, - fmOPLPostEffectHandler + fmEffectHandlerMap, + fmOPLPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_OPL3]=new DivSysDef( @@ -1381,8 +1019,8 @@ void DivEngine::registerSystems() { {DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM}, {DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL}, {}, - oplEffectHandler, - fmOPLPostEffectHandler + fmEffectHandlerMap, + fmOPLPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_MULTIPCM]=new DivSysDef( @@ -1429,27 +1067,12 @@ void DivEngine::registerSystems() { {DIV_CH_WAVE, DIV_CH_PCM, DIV_CH_WAVE, DIV_CH_NOISE}, {DIV_INS_SWAN, DIV_INS_SWAN, DIV_INS_SWAN, DIV_INS_SWAN}, {DIV_INS_NULL, DIV_INS_AMIGA, DIV_INS_NULL, DIV_INS_NULL}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x10: // select waveform - dispatchCmd(DivCommand(DIV_CMD_WAVE,ch,effectVal)); - break; - case 0x11: // noise mode - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); - break; - case 0x12: // sweep period - dispatchCmd(DivCommand(DIV_CMD_WS_SWEEP_TIME,ch,effectVal)); - break; - case 0x13: // sweep amount - dispatchCmd(DivCommand(DIV_CMD_WS_SWEEP_AMOUNT,ch,effectVal)); - break; - case 0x17: // PCM enable - dispatchCmd(DivCommand(DIV_CMD_SAMPLE_MODE,ch,(effectVal>0))); - break; - default: - return false; - } - return true; + { + {0x10, {DIV_CMD_WAVE, "10xx: Set waveform"}}, + {0x11, {DIV_CMD_STD_NOISE_MODE, "11xx: Setup noise mode (0: disabled; 1-8: enabled/tap)"}}, + {0x12, {DIV_CMD_WS_SWEEP_TIME, "12xx: Setup sweep period (0: disabled; 1-20: enabled/period)"}}, + {0x13, {DIV_CMD_WS_SWEEP_AMOUNT, "13xx: Set sweep amount"}}, + {0x17, {DIV_CMD_SAMPLE_MODE, "17xx: Toggle PCM mode"}}, } ); @@ -1461,17 +1084,10 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM}, {DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ}, {}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x2f: // toggle hard-reset - dispatchCmd(DivCommand(DIV_CMD_FM_HARD_RESET,ch,effectVal)); - break; - default: - return false; - } - return true; + { + {0x2f, {DIV_CMD_FM_HARD_RESET, "2Fxx: Toggle hard envelope reset on new notes"}}, }, - fmPostEffectHandler + fmOPZPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_POKEMINI]=new DivSysDef( @@ -1491,8 +1107,8 @@ void DivEngine::registerSystems() { {DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM}, {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, {}, - [](int,unsigned char,unsigned char) -> bool {return false;}, - segaPCMPostEffectHandler + {}, + segaPCMPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_VBOY]=new DivSysDef( @@ -1512,8 +1128,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM}, {DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL}, {}, - oplEffectHandler, - fmOPLLPostEffectHandler + fmEffectHandlerMap, + fmOPLLPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_YM2610B]=new DivSysDef( @@ -1524,8 +1140,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM}, {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, {}, - fmHardResetEffectHandler, - fmPostEffectHandler + fmEffectHandlerMap, + fmOPNPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_SFX_BEEPER]=new DivSysDef( @@ -1536,18 +1152,9 @@ void DivEngine::registerSystems() { {DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE}, {DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER}, {}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x12: // pulse width - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); - break; - case 0x17: // overlay sample - dispatchCmd(DivCommand(DIV_CMD_SAMPLE_MODE,ch,effectVal)); - break; - default: - return false; - } - return true; + { + {0x12, {DIV_CMD_STD_NOISE_MODE, "12xx: Set pulse width"}}, + {0x17, {DIV_CMD_SAMPLE_MODE, "17xx: Trigger overlay drum"}}, } ); @@ -1559,8 +1166,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM}, {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM}, {DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_AMIGA}, - opn2EffectHandler, - fmPostEffectHandler + fmOPN2EffectHandlerMap, + fmOPN2PostEffectHandlerMap ); sysDefs[DIV_SYSTEM_SCC]=new DivSysDef( @@ -1571,23 +1178,9 @@ void DivEngine::registerSystems() { {DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE}, {DIV_INS_SCC, DIV_INS_SCC, DIV_INS_SCC, DIV_INS_SCC, DIV_INS_SCC}, {}, - waveOnlyEffectHandler + waveOnlyEffectHandlerMap ); - auto oplDrumsEffectHandler=[this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x18: // drum mode toggle - dispatchCmd(DivCommand(DIV_CMD_FM_EXTCH,ch,effectVal)); - break; - case 0x30: // toggle hard-reset - dispatchCmd(DivCommand(DIV_CMD_FM_HARD_RESET,ch,effectVal)); - break; - default: - return false; - } - return true; - }; - sysDefs[DIV_SYSTEM_OPL_DRUMS]=new DivSysDef( "Yamaha YM3526 (OPL) with drums", NULL, 0xa2, 0, 11, true, false, 0x151, false, "the OPL chip but with drums mode enabled.", @@ -1596,8 +1189,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE}, {DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS}, {DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL}, - oplDrumsEffectHandler, - fmOPLPostEffectHandler + fmOPLDrumsEffectHandlerMap, + fmOPLPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_OPL2_DRUMS]=new DivSysDef( @@ -1608,8 +1201,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE}, {DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS}, {DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL}, - oplDrumsEffectHandler, - fmOPLPostEffectHandler + fmOPLDrumsEffectHandlerMap, + fmOPLPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_OPL3_DRUMS]=new DivSysDef( @@ -1620,8 +1213,8 @@ void DivEngine::registerSystems() { {DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE}, {DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS}, {DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL}, - oplDrumsEffectHandler, - fmOPLPostEffectHandler + fmOPLDrumsEffectHandlerMap, + fmOPLPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_YM2610_FULL]=new DivSysDef( @@ -1632,8 +1225,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM}, {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, {}, - fmHardResetEffectHandler, - fmPostEffectHandler + fmEffectHandlerMap, + fmOPNPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_YM2610_FULL_EXT]=new DivSysDef( @@ -1644,8 +1237,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM}, {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, {}, - fmHardResetEffectHandler, - fmPostEffectHandler + fmEffectHandlerMap, + fmOPNPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_OPLL_DRUMS]=new DivSysDef( @@ -1656,10 +1249,16 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE}, {DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL}, {}, - oplDrumsEffectHandler, - fmOPLLPostEffectHandler + fmOPLDrumsEffectHandlerMap, + fmOPLLPostEffectHandlerMap ); + EffectHandlerMap lynxEffectHandlerMap; + const EffectHandler lynxLFSRHandler(DIV_CMD_LYNX_LFSR_LOAD, "3xxx: Load LFSR (0 to FFF)", effectValLong<12>); + for (int i=0; i<16; i++) { + lynxEffectHandlerMap.emplace(0x30+i, lynxLFSRHandler); + } + sysDefs[DIV_SYSTEM_LYNX]=new DivSysDef( "Atari Lynx", NULL, 0xa8, 0, 4, false, true, 0, false, "a portable console made by Atari. it has all of Atari's trademark waveforms.", @@ -1668,17 +1267,20 @@ void DivEngine::registerSystems() { {DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE}, {DIV_INS_MIKEY, DIV_INS_MIKEY, DIV_INS_MIKEY, DIV_INS_MIKEY}, {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, - [](int,unsigned char,unsigned char) -> bool {return false;}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - if (effect>=0x30 && effect<0x40) { - int value=((int)(effect&0x0f)<<8)|effectVal; - dispatchCmd(DivCommand(DIV_CMD_LYNX_LFSR_LOAD,ch,value)); - return true; - } - return false; - } + {}, + lynxEffectHandlerMap ); + EffectHandlerMap qSoundEffectHandlerMap={ + {0x10, {DIV_CMD_QSOUND_ECHO_FEEDBACK, "10xx: Set echo feedback level (00 to FF)"}}, + {0x11, {DIV_CMD_QSOUND_ECHO_LEVEL, "11xx: Set channel echo level (00 to FF)"}}, + {0x12, {DIV_CMD_QSOUND_SURROUND, "12xx: Toggle QSound algorithm (0: disabled; 1: enabled)"}}, + }; + const EffectHandler qSoundEchoDelayHandler(DIV_CMD_QSOUND_ECHO_DELAY, "3xxx: Set echo delay buffer length (000 to AA5)", effectValLong<12>); + for (int i=0; i<16; i++) { + qSoundEffectHandlerMap.emplace(0x30+i, qSoundEchoDelayHandler); + } + sysDefs[DIV_SYSTEM_QSOUND]=new DivSysDef( "Capcom QSound", NULL, 0xe0, 0, 19, false, true, 0x161, false, "used in some of Capcom's arcade boards. surround-like sampled sound with echo.", @@ -1687,27 +1289,7 @@ void DivEngine::registerSystems() { {DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE}, {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, {}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x10: // echo feedback - dispatchCmd(DivCommand(DIV_CMD_QSOUND_ECHO_FEEDBACK,ch,effectVal)); - break; - case 0x11: // echo level - dispatchCmd(DivCommand(DIV_CMD_QSOUND_ECHO_LEVEL,ch,effectVal)); - break; - case 0x12: // surround - dispatchCmd(DivCommand(DIV_CMD_QSOUND_SURROUND,ch,effectVal)); - break; - default: - if ((effect&0xf0)==0x30) { - dispatchCmd(DivCommand(DIV_CMD_QSOUND_ECHO_DELAY,ch,((effect & 0x0f) << 8) | effectVal)); - } else { - return false; - } - break; - } - return true; - } + qSoundEffectHandlerMap ); sysDefs[DIV_SYSTEM_VERA]=new DivSysDef( @@ -1718,18 +1300,9 @@ void DivEngine::registerSystems() { {DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PCM}, {DIV_INS_VERA, DIV_INS_VERA, DIV_INS_VERA, DIV_INS_VERA, DIV_INS_VERA, DIV_INS_VERA, DIV_INS_VERA, DIV_INS_VERA, DIV_INS_VERA, DIV_INS_VERA, DIV_INS_VERA, DIV_INS_VERA, DIV_INS_VERA, DIV_INS_VERA, DIV_INS_VERA, DIV_INS_VERA, DIV_INS_AMIGA}, {}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x20: // select waveform - dispatchCmd(DivCommand(DIV_CMD_WAVE,ch,effectVal)); - break; - case 0x22: // duty - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); - break; - default: - return false; - } - return true; + { + {0x20, {DIV_CMD_WAVE, "20xx: Set waveform"}}, + {0x22, {DIV_CMD_STD_NOISE_MODE, "22xx: Set duty cycle (0 to 3F)"}}, } ); @@ -1741,8 +1314,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM}, {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, {}, - fmHardResetEffectHandler, - fmPostEffectHandler + fmEffectHandlerMap, + fmOPNPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_SEGAPCM_COMPAT]=new DivSysDef( @@ -1753,8 +1326,8 @@ void DivEngine::registerSystems() { {DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM}, {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, {}, - [](int,unsigned char,unsigned char) -> bool {return false;}, - segaPCMPostEffectHandler + {}, + segaPCMPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_X1_010]=new DivSysDef( @@ -1765,46 +1338,18 @@ void DivEngine::registerSystems() { {DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE}, {DIV_INS_X1_010, DIV_INS_X1_010, DIV_INS_X1_010, DIV_INS_X1_010, DIV_INS_X1_010, DIV_INS_X1_010, DIV_INS_X1_010, DIV_INS_X1_010, DIV_INS_X1_010, DIV_INS_X1_010, DIV_INS_X1_010, DIV_INS_X1_010, DIV_INS_X1_010, DIV_INS_X1_010, DIV_INS_X1_010, DIV_INS_X1_010}, {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x10: // select waveform - dispatchCmd(DivCommand(DIV_CMD_WAVE,ch,effectVal)); - break; - case 0x11: // select envelope shape - dispatchCmd(DivCommand(DIV_CMD_X1_010_ENVELOPE_SHAPE,ch,effectVal)); - break; - case 0x17: // PCM enable - dispatchCmd(DivCommand(DIV_CMD_SAMPLE_MODE,ch,(effectVal>0))); - break; - default: - return false; - } - return true; + { + {0x10, {DIV_CMD_WAVE, "10xx: Set waveform"}}, + {0x11, {DIV_CMD_X1_010_ENVELOPE_SHAPE, "11xx: Set envelope shape"}}, + {0x17, {DIV_CMD_SAMPLE_MODE, "17xx: Toggle PCM mode"}}, }, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x20: // PCM frequency - dispatchCmd(DivCommand(DIV_CMD_SAMPLE_FREQ,ch,effectVal)); - break; - case 0x22: // envelope mode - dispatchCmd(DivCommand(DIV_CMD_X1_010_ENVELOPE_MODE,ch,effectVal)); - break; - case 0x23: // envelope period - dispatchCmd(DivCommand(DIV_CMD_X1_010_ENVELOPE_PERIOD,ch,effectVal)); - break; - case 0x25: // envelope slide up - dispatchCmd(DivCommand(DIV_CMD_X1_010_ENVELOPE_SLIDE,ch,effectVal)); - break; - case 0x26: // envelope slide down - dispatchCmd(DivCommand(DIV_CMD_X1_010_ENVELOPE_SLIDE,ch,-effectVal)); - break; - case 0x29: // auto-envelope - dispatchCmd(DivCommand(DIV_CMD_X1_010_AUTO_ENVELOPE,ch,effectVal)); - break; - default: - return false; - } - return true; + { + {0x20, {DIV_CMD_SAMPLE_FREQ, "20xx: Set PCM frequency (1 to FF)"}}, + {0x22, {DIV_CMD_X1_010_ENVELOPE_MODE, "22xx: Set envelope mode (bit 0: enable; bit 1: one-shot; bit 2: split shape to L/R; bit 3/5: H.invert right/left; bit 4/6: V.invert right/left)"}}, + {0x23, {DIV_CMD_X1_010_ENVELOPE_PERIOD, "23xx: Set envelope period"}}, + {0x25, {DIV_CMD_X1_010_ENVELOPE_SLIDE, "25xx: Envelope slide up"}}, + {0x26, {DIV_CMD_X1_010_ENVELOPE_SLIDE, "26xx: Envelope slide down", negEffectVal}}, + {0x29, {DIV_CMD_X1_010_AUTO_ENVELOPE, "29xy: Set auto-envelope (x: numerator; y: denominator)"}}, } ); @@ -1816,7 +1361,7 @@ void DivEngine::registerSystems() { {DIV_CH_WAVE, DIV_CH_WAVE}, {DIV_INS_SCC, DIV_INS_SCC}, {}, - waveOnlyEffectHandler + waveOnlyEffectHandlerMap ); // to Grauw: feel free to change this to 24 during development of OPL4's PCM part. @@ -1855,8 +1400,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_PCM}, {DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_AMIGA}, {}, - oplEffectHandler, - fmOPLPostEffectHandler + fmEffectHandlerMap, + fmOPLPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_Y8950_DRUMS]=new DivSysDef( @@ -1867,8 +1412,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_PCM}, {DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_AMIGA}, {DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_NULL}, - oplEffectHandler, - fmOPLPostEffectHandler + fmEffectHandlerMap, + fmOPLPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_SCC_PLUS]=new DivSysDef( @@ -1879,9 +1424,34 @@ void DivEngine::registerSystems() { {DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE}, {DIV_INS_SCC, DIV_INS_SCC, DIV_INS_SCC, DIV_INS_SCC, DIV_INS_SCC}, {}, - waveOnlyEffectHandler + waveOnlyEffectHandlerMap ); + EffectHandlerMap suEffectHandlerMap={ + {0x10, {DIV_CMD_WAVE, "10xx: Set waveform (0 to 7)"}}, + {0x12, {DIV_CMD_STD_NOISE_MODE, "22xx: Set envelope mode (bit 0: enable; bit 1: one-shot; bit 2: split shape to L/R; bit 3/5: H.invert right/left; bit 4/6: V.invert right/left)"}}, + {0x13, {DIV_CMD_C64_RESONANCE, "23xx: Set envelope period"}}, + {0x14, {DIV_CMD_C64_FILTER_MODE, "25xx: Envelope slide up"}}, + {0x15, {DIV_CMD_SU_SWEEP_PERIOD_LOW, "15xx: Set frequency sweep period low byte", constVal<0>, effectVal}}, + {0x16, {DIV_CMD_SU_SWEEP_PERIOD_HIGH, "16xx: Set frequency sweep period high byte", constVal<0>, effectVal}}, + {0x17, {DIV_CMD_SU_SWEEP_PERIOD_LOW, "17xx: Set volume sweep period low byte", constVal<1>, effectVal}}, + {0x18, {DIV_CMD_SU_SWEEP_PERIOD_HIGH, "18xx: Set volume sweep period high byte", constVal<1>, effectVal}}, + {0x19, {DIV_CMD_SU_SWEEP_PERIOD_LOW, "19xx: Set cutoff sweep period low byte", constVal<2>, effectVal}}, + {0x1a, {DIV_CMD_SU_SWEEP_PERIOD_HIGH, "1axx: Set cutoff sweep period high byte", constVal<2>, effectVal}}, + {0x1b, {DIV_CMD_SU_SWEEP_BOUND, "1Bxx: Set frequency sweep boundary", constVal<0>, effectVal}}, + {0x1c, {DIV_CMD_SU_SWEEP_BOUND, "1Cxx: Set volume sweep boundary", constVal<1>, effectVal}}, + {0x1d, {DIV_CMD_SU_SWEEP_BOUND, "1Dxx: Set cutoff sweep boundary", constVal<2>, effectVal}}, + {0x1e, {DIV_CMD_SU_SYNC_PERIOD_LOW, "1Exx: Set phase reset period low byte"}}, + {0x1f, {DIV_CMD_SU_SYNC_PERIOD_HIGH, "1Fxx: Set phase reset period high byte"}}, + {0x20, {DIV_CMD_SU_SWEEP_ENABLE, "20xx: Toggle frequency sweep (bit 0-6: speed; bit 7: direction is up)", constVal<0>, effectVal}}, + {0x21, {DIV_CMD_SU_SWEEP_ENABLE, "21xx: Toggle volume sweep (bit 0-4: speed; bit 5: direciton is up; bit 6: loop; bit 7: alternate)", constVal<1>, effectVal}}, + {0x22, {DIV_CMD_SU_SWEEP_ENABLE, "22xx: Toggle cutoff sweep (bit 0-6: speed; bit 7: direction is up)", constVal<2>, effectVal}}, + }; + const EffectHandler suCutoffHandler(DIV_CMD_C64_FINE_DUTY, "4xxx: Set cutoff (0 to FFF)", effectValLong<12>); + for (int i=0; i<16; i++) { + suEffectHandlerMap.emplace(0x40+i, suCutoffHandler); + } + sysDefs[DIV_SYSTEM_SOUND_UNIT]=new DivSysDef( "tildearrow Sound Unit", NULL, 0xb5, 0, 8, false, true, 0, false, "tildearrow's fantasy sound chip. put SID, AY and VERA in a blender, and you get this!", @@ -1890,74 +1460,8 @@ void DivEngine::registerSystems() { {DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE}, {DIV_INS_SU, DIV_INS_SU, DIV_INS_SU, DIV_INS_SU, DIV_INS_SU, DIV_INS_SU, DIV_INS_SU, DIV_INS_SU}, {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, - [](int,unsigned char,unsigned char) -> bool {return false;}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x10: // waveform - dispatchCmd(DivCommand(DIV_CMD_WAVE,ch,effectVal)); - break; - case 0x12: // duty cycle - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); - break; - case 0x13: // resonance - dispatchCmd(DivCommand(DIV_CMD_C64_RESONANCE,ch,effectVal)); - break; - case 0x14: // filter mode - dispatchCmd(DivCommand(DIV_CMD_C64_FILTER_MODE,ch,effectVal)); - break; - case 0x15: // freq sweep - dispatchCmd(DivCommand(DIV_CMD_SU_SWEEP_PERIOD_LOW,ch,0,effectVal)); - break; - case 0x16: // freq sweep - dispatchCmd(DivCommand(DIV_CMD_SU_SWEEP_PERIOD_HIGH,ch,0,effectVal)); - break; - case 0x17: // vol sweep - dispatchCmd(DivCommand(DIV_CMD_SU_SWEEP_PERIOD_LOW,ch,1,effectVal)); - break; - case 0x18: // vol sweep - dispatchCmd(DivCommand(DIV_CMD_SU_SWEEP_PERIOD_HIGH,ch,1,effectVal)); - break; - case 0x19: // cut sweep - dispatchCmd(DivCommand(DIV_CMD_SU_SWEEP_PERIOD_LOW,ch,2,effectVal)); - break; - case 0x1a: // cut sweep - dispatchCmd(DivCommand(DIV_CMD_SU_SWEEP_PERIOD_HIGH,ch,2,effectVal)); - break; - case 0x1b: // freq sweep bound - dispatchCmd(DivCommand(DIV_CMD_SU_SWEEP_BOUND,ch,0,effectVal)); - break; - case 0x1c: // vol sweep bound - dispatchCmd(DivCommand(DIV_CMD_SU_SWEEP_BOUND,ch,1,effectVal)); - break; - case 0x1d: // cut sweep bound - dispatchCmd(DivCommand(DIV_CMD_SU_SWEEP_BOUND,ch,2,effectVal)); - break; - case 0x1e: // sync low - dispatchCmd(DivCommand(DIV_CMD_SU_SYNC_PERIOD_LOW,ch,effectVal)); - break; - case 0x1f: // sync high - dispatchCmd(DivCommand(DIV_CMD_SU_SYNC_PERIOD_HIGH,ch,effectVal)); - break; - case 0x20: // freq sweep enable - dispatchCmd(DivCommand(DIV_CMD_SU_SWEEP_ENABLE,ch,0,effectVal)); - break; - case 0x21: // vol sweep enable - dispatchCmd(DivCommand(DIV_CMD_SU_SWEEP_ENABLE,ch,1,effectVal)); - break; - case 0x22: // cut sweep enable - dispatchCmd(DivCommand(DIV_CMD_SU_SWEEP_ENABLE,ch,2,effectVal)); - break; - case 0x40: case 0x41: case 0x42: case 0x43: - case 0x44: case 0x45: case 0x46: case 0x47: - case 0x48: case 0x49: case 0x4a: case 0x4b: - case 0x4c: case 0x4d: case 0x4e: case 0x4f: // cutoff - dispatchCmd(DivCommand(DIV_CMD_C64_FINE_CUTOFF,ch,(((effect&0x0f)<<8)|effectVal)*4)); - break; - default: - return false; - } - return true; - } + {}, + suEffectHandlerMap ); sysDefs[DIV_SYSTEM_MSM6295]=new DivSysDef( @@ -1968,15 +1472,8 @@ void DivEngine::registerSystems() { {DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM}, {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, {}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x20: // select rate - dispatchCmd(DivCommand(DIV_CMD_SAMPLE_FREQ,ch,effectVal)); - break; - default: - return false; - } - return true; + { + {0x20, {DIV_CMD_SAMPLE_FREQ, "20xx: Set chip output rate (0: clock/132; 1: clock/165)"}}, } ); @@ -1988,18 +1485,9 @@ void DivEngine::registerSystems() { {DIV_CH_PCM}, {DIV_INS_AMIGA}, {}, - [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x20: // select rate - dispatchCmd(DivCommand(DIV_CMD_SAMPLE_FREQ,ch,effectVal)); - break; - case 0x21: // select clock - dispatchCmd(DivCommand(DIV_CMD_SAMPLE_MODE,ch,effectVal)); - break; - default: - return false; - } - return true; + { + {0x20, {DIV_CMD_SAMPLE_FREQ, "20xx: Set frequency divider (0-2)"}}, + {0x21, {DIV_CMD_SAMPLE_MODE, "21xx: Select clock rate (0: full; 1: half)"}}, } ); @@ -2012,18 +1500,9 @@ void DivEngine::registerSystems() { {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA} ); - auto namcoEffectHandler=[this](int ch, unsigned char effect, unsigned char effectVal) -> bool { - switch (effect) { - case 0x10: // select waveform - dispatchCmd(DivCommand(DIV_CMD_WAVE,ch,effectVal)); - break; - case 0x11: // noise mode - dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); - break; - default: - return false; - } - return true; + EffectHandlerMap namcoEffectHandlerMap={ + {0x10, {DIV_CMD_WAVE, "10xx: Set waveform"}}, + {0x11, {DIV_CMD_STD_NOISE_MODE, "11xx: Toggle noise mode"}}, }; sysDefs[DIV_SYSTEM_NAMCO]=new DivSysDef( @@ -2034,7 +1513,7 @@ void DivEngine::registerSystems() { {DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE}, {DIV_INS_NAMCO, DIV_INS_NAMCO, DIV_INS_NAMCO}, {}, - namcoEffectHandler + namcoEffectHandlerMap ); sysDefs[DIV_SYSTEM_NAMCO_15XX]=new DivSysDef( @@ -2045,7 +1524,7 @@ void DivEngine::registerSystems() { {DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE}, {DIV_INS_NAMCO, DIV_INS_NAMCO, DIV_INS_NAMCO, DIV_INS_NAMCO, DIV_INS_NAMCO, DIV_INS_NAMCO, DIV_INS_NAMCO, DIV_INS_NAMCO}, {}, - namcoEffectHandler + namcoEffectHandlerMap ); sysDefs[DIV_SYSTEM_NAMCO_CUS30]=new DivSysDef( @@ -2056,7 +1535,7 @@ void DivEngine::registerSystems() { {DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE}, {DIV_INS_NAMCO, DIV_INS_NAMCO, DIV_INS_NAMCO, DIV_INS_NAMCO, DIV_INS_NAMCO, DIV_INS_NAMCO, DIV_INS_NAMCO, DIV_INS_NAMCO}, {}, - namcoEffectHandler + namcoEffectHandlerMap ); // replace with an 8-channel chip in a future @@ -2077,8 +1556,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_PCM, DIV_CH_PCM}, {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AMIGA}, {DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_AMIGA, DIV_INS_NULL}, - opn2EffectHandler, - fmPostEffectHandler + fmOPN2EffectHandlerMap, + fmOPN2PostEffectHandlerMap ); sysDefs[DIV_SYSTEM_YM2612_FRAC_EXT]=new DivSysDef( @@ -2089,8 +1568,8 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_NOISE}, {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AMIGA, DIV_INS_FM}, {DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_AMIGA, DIV_INS_NULL, DIV_INS_NULL}, - opn2EffectHandler, - fmPostEffectHandler + fmOPN2EffectHandlerMap, + fmOPN2PostEffectHandlerMap ); sysDefs[DIV_SYSTEM_T6W28]=new DivSysDef( @@ -2101,15 +1580,8 @@ void DivEngine::registerSystems() { {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; + { + {0x20, {DIV_CMD_STD_NOISE_MODE, "20xy: Set noise mode (x: preset/variable; y: thin pulse/noise)"}} } );