From 6e7b4d7e7f6d5e04e705ea55703b77ecf8f2c68a Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 4 May 2022 17:39:22 -0500 Subject: [PATCH] the final part of extra FM effects --- TODO.md | 1 - papers/doc/7-systems/opll.md | 8 ++-- papers/doc/7-systems/ym2612.md | 16 +++---- src/engine/platform/arcade.cpp | 48 ++++++++++++++++++++ src/engine/platform/genesis.cpp | 48 ++++++++++++++++++++ src/engine/platform/opl.cpp | 42 +++++++++++++++++ src/engine/platform/opll.cpp | 30 +++++++++++++ src/engine/platform/tx81z.cpp | 80 ++++++++++++++++++++++++++++++++- src/engine/platform/ym2610.cpp | 48 ++++++++++++++++++++ src/engine/platform/ym2610b.cpp | 48 ++++++++++++++++++++ src/gui/guiConst.cpp | 32 ++++++------- 11 files changed, 370 insertions(+), 31 deletions(-) diff --git a/TODO.md b/TODO.md index 710e6091..80357e3e 100644 --- a/TODO.md +++ b/TODO.md @@ -12,7 +12,6 @@ - SCC/SCC+ system - maybe YMU759 ADPCM channel - ADPCM chips -- more effects for FM param control - Game Boy envelope macro/sequence - option to display chip names instead of "multi-system" on title bar - rewrite the system name detection function anyway diff --git a/papers/doc/7-systems/opll.md b/papers/doc/7-systems/opll.md index 4e91c137..d0e6475c 100644 --- a/papers/doc/7-systems/opll.md +++ b/papers/doc/7-systems/opll.md @@ -2,17 +2,17 @@ the YM2413, otherwise known as OPLL, is a cost-reduced FM synthesis sound chip, based on the Yamaha YM3812 (OPL2). thought OPL was downgraded enough? :p -OPLL spawned also a few derivative chips, the best known of these is: -- the myth. the legend. THE VRC7. 6 channels, *rather interesting* instruments sound bank, no drums mode +OPLL also spawned a few derivative chips, the best known of these is: +- the famous Konami VRC7. used in the Japan-only video game Lagrange Point, it was **another** cost reduction on top of the OPLL! this time just 6 channels... - Yamaha YM2423, same chip as YM2413, just a different patch set -- Yamaha YMF281, ditto +- Yamaha YMF281, ditto # technical specifications the YM2413 is equipped with the following features: - 9 channels of 2 operator FM synthesis -- A drum/percussion mode, replacing the last 3 voices with 3 rhythm channels +- A drum/percussion mode, replacing the last 3 voices with 5 rhythm channels - 1 user-definable patch (this patch can be changed throughout the course of the song) - 15 pre-defined patches which can all be used at the same time - Support for ADSR on both the modulator and the carrier diff --git a/papers/doc/7-systems/ym2612.md b/papers/doc/7-systems/ym2612.md index c32521f2..e86dde9d 100644 --- a/papers/doc/7-systems/ym2612.md +++ b/papers/doc/7-systems/ym2612.md @@ -39,14 +39,14 @@ one of two chips that powered the Sega Genesis. It is a six-channel, four-operat - `53xy` set DT of operator. - `x` is the operator (1-4). a value of 0 means "all operators". - `y` is the value: - - 0: +0 - - 1: +1 - - 2: +2 - - 3: +3 - - 4: -0 - - 5: -3 - - 6: -2 - - 7: -1 + - 0: -3 + - 1: -2 + - 2: -1 + - 3: 0 + - 4: 1 + - 5: 2 + - 6: 3 + - 7: -0 - `54xy` set RS of operator. - `x` is the operator (1-4). a value of 0 means "all operators". - `y` is the value. diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index 2c6161e5..6bd4e203 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -135,6 +135,54 @@ const char* DivPlatformArcade::getEffectName(unsigned char effect) { 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; } diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 67970298..0f665cba 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -77,6 +77,54 @@ const char* DivPlatformGenesis::getEffectName(unsigned char effect) { 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; } diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 7dad9e1c..c056231e 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -197,6 +197,48 @@ const char* DivPlatformOPL::getEffectName(unsigned char effect) { 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; } diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index 1e29a1e4..70b25dc0 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -55,6 +55,36 @@ const char* DivPlatformOPLL::getEffectName(unsigned char effect) { 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; } diff --git a/src/engine/platform/tx81z.cpp b/src/engine/platform/tx81z.cpp index 277de883..056eeaac 100644 --- a/src/engine/platform/tx81z.cpp +++ b/src/engine/platform/tx81z.cpp @@ -137,8 +137,84 @@ const char* DivPlatformTX81Z::getEffectName(unsigned char effect) { case 0x1f: return "1Fxx: Set PM depth (0 to 7F)"; break; - case 0x30: - return "30xx: Toggle hard envelope reset on new notes"; + 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; diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 85aa3633..54bbbd21 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -397,6 +397,54 @@ const char* DivPlatformYM2610::getEffectName(unsigned char effect) { 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; } diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 83aa0fb9..b36cc87f 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -377,6 +377,54 @@ const char* DivPlatformYM2610B::getEffectName(unsigned char effect) { 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; } diff --git a/src/gui/guiConst.cpp b/src/gui/guiConst.cpp index 0cc1894a..ca064739 100644 --- a/src/gui/guiConst.cpp +++ b/src/gui/guiConst.cpp @@ -233,22 +233,22 @@ const FurnaceGUIColors fxColors[256]={ GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, // 50-5F - GUI_COLOR_PATTERN_EFFECT_INVALID, - GUI_COLOR_PATTERN_EFFECT_INVALID, - GUI_COLOR_PATTERN_EFFECT_INVALID, - GUI_COLOR_PATTERN_EFFECT_INVALID, - GUI_COLOR_PATTERN_EFFECT_INVALID, - GUI_COLOR_PATTERN_EFFECT_INVALID, - GUI_COLOR_PATTERN_EFFECT_INVALID, - GUI_COLOR_PATTERN_EFFECT_INVALID, - GUI_COLOR_PATTERN_EFFECT_INVALID, - GUI_COLOR_PATTERN_EFFECT_INVALID, - GUI_COLOR_PATTERN_EFFECT_INVALID, - GUI_COLOR_PATTERN_EFFECT_INVALID, - GUI_COLOR_PATTERN_EFFECT_INVALID, - GUI_COLOR_PATTERN_EFFECT_INVALID, - GUI_COLOR_PATTERN_EFFECT_INVALID, - GUI_COLOR_PATTERN_EFFECT_INVALID, + GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, + GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, + GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, + GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, + GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, + GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, + GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, + GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, + GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, + GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, + GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, + GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, + GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, + GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, + GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, + GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY, // 60-6F GUI_COLOR_PATTERN_EFFECT_INVALID,