2022-02-17 13:08:17 -05:00
/**
* Furnace Tracker - multi - system chiptune tracker
2025-01-28 18:49:19 -05:00
* Copyright ( C ) 2021 - 2025 tildearrow and contributors
2022-02-17 13:08:17 -05:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License along
* with this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*/
2022-12-14 23:38:38 -05:00
# define _USE_MATH_DEFINES
2022-02-17 13:08:17 -05:00
# include "gui.h"
2023-08-21 17:24:41 -05:00
# include "../ta-log.h"
2022-02-17 13:08:17 -05:00
# include "imgui_internal.h"
2022-08-20 01:10:30 -05:00
# include "../engine/macroInt.h"
2024-09-21 17:37:30 -05:00
// i don't know whether this is the right thing to do
2024-07-31 19:22:01 +03:00
# include "../engine/platform/sound/sid3.h"
2022-02-17 13:08:17 -05:00
# include "IconsFontAwesome4.h"
2023-10-28 19:15:32 -05:00
# include "furIcons.h"
2022-02-17 13:08:17 -05:00
# include "misc/cpp/imgui_stdlib.h"
# include "guiConst.h"
# include "intConst.h"
# include <fmt/printf.h>
2022-02-23 11:51:02 -05:00
# include <imgui.h>
2022-02-17 13:08:17 -05:00
# include "plot_nolerp.h"
2024-08-01 22:05:18 +03:00
# include "util.h"
2022-02-17 13:08:17 -05:00
2022-11-15 17:51:43 -05:00
extern " C " {
# include "../../extern/Nuked-OPLL/opll.h"
}
2022-02-17 13:08:17 -05:00
const char * ssgEnvTypes [ 8 ] = {
2024-05-26 19:31:17 -05:00
_N ( " Down Down Down " ) ,
_N ( " Down. " ) ,
_N ( " Down Up Down Up " ) ,
_N ( " Down UP " ) ,
_N ( " Up Up Up " ) ,
_N ( " Up. " ) ,
_N ( " Up Down Up Down " ) ,
_N ( " Up DOWN " )
2022-02-17 13:08:17 -05:00
} ;
2024-09-18 14:48:10 +07:00
const char * fmParamNames [ 3 ] [ 33 ] = {
2025-01-28 03:52:17 -05:00
{ _N ( " Algorithm " ) , _N ( " Feedback " ) , _N ( " LFO > Freq " ) , _N ( " LFO > Amp " ) , _N ( " Attack " ) , _N ( " Decay " ) , _N ( " Decay 2 " ) , _N ( " Release " ) , _N ( " Sustain " ) , _N ( " Level " ) , _N ( " EnvScale " ) , _N ( " Multiplier " ) , _N ( " Detune " ) , _N ( " Detune 2 " ) , _N ( " SSG-EG " ) , _N ( " AM " ) , _N ( " AM Depth " ) , _N ( " Vibrato Depth " ) , _N ( " Sustained " ) , _N ( " Sustained " ) , _N ( " Level Scaling " ) , _N ( " Sustain " ) , _N ( " Vibrato " ) , _N ( " Waveform " ) , _N ( " Scale Rate " ) , _N ( " OP2 Half Sine " ) , _N ( " OP1 Half Sine " ) , _N ( " EnvShift " ) , _N ( " Reverb " ) , _N ( " Fine " ) , _N ( " LFO2 > Freq " ) , _N ( " LFO2 > Amp " ) , _N ( " Octave " ) } ,
{ " ALG " , " FB " , " FMS/PMS " , " AMS " , " AR " , " DR " , " SR " , " RR " , " SL " , " TL " , " KS " , " MULT " , " DT " , " DT2 " , " SSG-EG " , " AM " , " AMD " , " FMD " , " EGT " , " EGT " , " KSL " , " SUS " , " VIB " , " WS " , " KSR " , " DC " , " DM " , " EGS " , " REV " , " Fine " , " FMS/PMS2 " , " AMS2 " , " Block " } ,
{ " ALG " , " FB " , " FMS/PMS " , " AMS " , " AR " , " DR " , " D2R " , " RR " , " SL " , " TL " , " RS " , " MULT " , " DT " , " DT2 " , " SSG-EG " , " AM " , " DAM " , " DVB " , " EGT " , " EGS " , " KSL " , " SUS " , " VIB " , " WS " , " KSR " , " DC " , " DM " , " EGS " , " REV " , " Fine " , " FMS/PMS2 " , " AMS2 " , " Block " }
2022-02-17 13:08:17 -05:00
} ;
2023-10-15 19:46:07 -03:00
const char * esfmParamLongNames [ 9 ] = {
2024-05-26 19:31:17 -05:00
_N ( " OP4 Noise Mode " ) ,
_N ( " Envelope Delay " ) ,
_N ( " Output Level " ) ,
_N ( " Modulation Input Level " ) ,
_N ( " Left Output " ) ,
_N ( " Right Output " ) ,
_N ( " Coarse Tune (semitones) " ) ,
_N ( " Detune " ) ,
_N ( " Fixed Frequency Mode " )
2023-10-14 08:10:37 -03:00
} ;
2023-10-15 19:46:07 -03:00
const char * esfmParamNames [ 9 ] = {
2024-05-26 19:31:17 -05:00
_N ( " OP4 Noise Mode " ) ,
_N ( " Env. Delay " ) ,
_N ( " Output Level " ) ,
_N ( " ModInput " ) ,
_N ( " Left " ) ,
_N ( " Right " ) ,
_N ( " Tune " ) ,
_N ( " Detune " ) ,
_N ( " Fixed " )
2023-10-14 17:09:18 -03:00
} ;
2023-10-15 19:46:07 -03:00
const char * esfmParamShortNames [ 9 ] = {
2023-10-26 09:45:46 -03:00
" NOI " , " DL " , " OL " , " MI " , " L " , " R " , " CT " , " DT " , " FIX "
2023-10-14 08:10:37 -03:00
} ;
2022-04-07 00:45:53 -05:00
const char * fmParamShortNames [ 3 ] [ 32 ] = {
{ " ALG " , " FB " , " FMS " , " AMS " , " A " , " D " , " D2 " , " R " , " S " , " TL " , " RS " , " ML " , " DT " , " DT2 " , " SSG " , " AM " , " DAM " , " DVB " , " SUS " , " SUS " , " KSL " , " SUS " , " VIB " , " WS " , " KSR " , " DC " , " DM " , " EGS " , " REV " , " Fine " , " FMS2 " , " AMS2 " } ,
{ " ALG " , " FB " , " FMS " , " AMS " , " A " , " D " , " SR " , " R " , " S " , " TL " , " KS " , " ML " , " DT " , " DT2 " , " SSG " , " AM " , " AMD " , " FMD " , " EGT " , " EGT " , " KSL " , " SUS " , " VIB " , " WS " , " KSR " , " DC " , " DM " , " EGS " , " REV " , " Fine " , " FMS2 " , " AMS2 " } ,
{ " ALG " , " FB " , " FMS " , " AMS " , " A " , " D " , " D2 " , " R " , " S " , " TL " , " RS " , " ML " , " DT " , " DT2 " , " SSG " , " AM " , " DAM " , " DVB " , " EGT " , " EGS " , " KSL " , " SUS " , " VIB " , " WS " , " KSR " , " DC " , " DM " , " EGS " , " REV " , " Fine " , " FMS2 " , " AMS2 " }
2022-03-27 03:29:45 -05:00
} ;
2022-08-02 23:16:42 -05:00
const char * opllVariants [ 4 ] = {
" OPLL " ,
" YMF281 " ,
" YM2423 " ,
" VRC7 "
} ;
const char * opllInsNames [ 4 ] [ 17 ] = {
/* YM2413 */ {
2024-05-26 19:31:17 -05:00
_N ( " User " ) ,
_N ( " 1. Violin " ) ,
_N ( " 2. Guitar " ) ,
_N ( " 3. Piano " ) ,
_N ( " 4. Flute " ) ,
_N ( " 5. Clarinet " ) ,
_N ( " 6. Oboe " ) ,
_N ( " 7. Trumpet " ) ,
_N ( " 8. Organ " ) ,
_N ( " 9. Horn " ) ,
_N ( " 10. Synth " ) ,
_N ( " 11. Harpsichord " ) ,
_N ( " 12. Vibraphone " ) ,
_N ( " 13. Synth Bass " ) ,
_N ( " 14. Acoustic Bass " ) ,
_N ( " 15. Electric Guitar " ) ,
_N ( " Drums " )
2022-08-02 23:16:42 -05:00
} ,
/* YMF281 */ {
2024-05-26 19:31:17 -05:00
_N ( " User " ) ,
_N ( " 1. Electric String " ) ,
_N ( " 2. Bow wow " ) ,
_N ( " 3. Electric Guitar " ) ,
_N ( " 4. Organ " ) ,
_N ( " 5. Clarinet " ) ,
_N ( " 6. Saxophone " ) ,
_N ( " 7. Trumpet " ) ,
_N ( " 8. Street Organ " ) ,
_N ( " 9. Synth Brass " ) ,
_N ( " 10. Electric Piano " ) ,
_N ( " 11. Bass " ) ,
_N ( " 12. Vibraphone " ) ,
_N ( " 13. Chime " ) ,
_N ( " 14. Tom Tom II " ) ,
_N ( " 15. Noise " ) ,
_N ( " Drums " )
2022-08-02 23:16:42 -05:00
} ,
/* YM2423 */ {
2024-05-26 19:31:17 -05:00
_N ( " User " ) ,
_N ( " 1. Strings " ) ,
_N ( " 2. Guitar " ) ,
_N ( " 3. Electric Guitar " ) ,
_N ( " 4. Electric Piano " ) ,
_N ( " 5. Flute " ) ,
_N ( " 6. Marimba " ) ,
_N ( " 7. Trumpet " ) ,
_N ( " 8. Harmonica " ) ,
_N ( " 9. Tuba " ) ,
_N ( " 10. Synth Brass " ) ,
_N ( " 11. Short Saw " ) ,
_N ( " 12. Vibraphone " ) ,
_N ( " 13. Electric Guitar 2 " ) ,
_N ( " 14. Synth Bass " ) ,
_N ( " 15. Sitar " ) ,
_N ( " Drums " )
2022-08-02 23:16:42 -05:00
} ,
// stolen from FamiTracker
/* VRC7 */ {
2024-05-26 19:31:17 -05:00
_N ( " User " ) ,
_N ( " 1. Bell " ) ,
_N ( " 2. Guitar " ) ,
_N ( " 3. Piano " ) ,
_N ( " 4. Flute " ) ,
_N ( " 5. Clarinet " ) ,
_N ( " 6. Rattling Bell " ) ,
_N ( " 7. Trumpet " ) ,
_N ( " 8. Reed Organ " ) ,
_N ( " 9. Soft Bell " ) ,
_N ( " 10. Xylophone " ) ,
_N ( " 11. Vibraphone " ) ,
_N ( " 12. Brass " ) ,
_N ( " 13. Bass Guitar " ) ,
_N ( " 14. Synth " ) ,
_N ( " 15. Chorus " ) ,
_N ( " Drums " )
2022-08-02 23:16:42 -05:00
}
2022-02-20 21:39:14 -05:00
} ;
2022-03-08 13:12:20 -05:00
const char * oplWaveforms [ 8 ] = {
2024-05-26 19:31:17 -05:00
_N ( " Sine " ) ,
_N ( " Half Sine " ) ,
_N ( " Absolute Sine " ) ,
_N ( " Quarter Sine " ) ,
_N ( " Squished Sine " ) ,
_N ( " Squished AbsSine " ) ,
_N ( " Square " ) ,
_N ( " Derived Square " )
2022-03-08 13:12:20 -05:00
} ;
2022-04-14 21:57:39 -05:00
const char * oplWaveformsStandard [ 8 ] = {
2024-05-26 19:31:17 -05:00
_N ( " Sine " ) ,
_N ( " Half Sine " ) ,
_N ( " Absolute Sine " ) ,
_N ( " Pulse Sine " ) ,
_N ( " Sine (Even Periods) " ) ,
_N ( " AbsSine (Even Periods) " ) ,
_N ( " Square " ) ,
_N ( " Derived Square " )
2022-04-14 21:57:39 -05:00
} ;
2022-03-08 13:46:48 -05:00
const char * opzWaveforms [ 8 ] = {
2024-05-26 19:31:17 -05:00
_N ( " Sine " ) ,
_N ( " Triangle " ) ,
_N ( " Cut Sine " ) ,
_N ( " Cut Triangle " ) ,
_N ( " Squished Sine " ) ,
_N ( " Squished Triangle " ) ,
_N ( " Squished AbsSine " ) ,
_N ( " Squished AbsTriangle " )
2022-03-08 13:46:48 -05:00
} ;
2022-05-30 18:37:07 -05:00
const char * oplDrumNames [ 4 ] = {
2024-05-26 19:31:17 -05:00
_N ( " Snare " ) ,
_N ( " Tom " ) ,
_N ( " Top " ) ,
_N ( " HiHat " )
2022-05-30 18:37:07 -05:00
} ;
2023-10-14 08:10:37 -03:00
const char * esfmNoiseModeNames [ 4 ] = {
2024-05-26 19:31:17 -05:00
_N ( " Normal " ) ,
_N ( " Snare " ) ,
_N ( " HiHat " ) ,
_N ( " Top " )
2023-10-24 14:29:37 -03:00
} ;
const char * esfmNoiseModeDescriptions [ 4 ] = {
2024-05-26 19:31:17 -05:00
_N ( " Noise disabled " ) ,
_N ( " Square + noise " ) ,
_N ( " Ringmod from OP3 + noise " ) ,
_N ( " Ringmod from OP3 + double pitch ModInput \n WARNING - has emulation issues; subject to change " )
2023-10-14 08:10:37 -03:00
} ;
2024-04-21 12:59:19 -05:00
const char * sid2WaveMixModes [ 5 ] = {
2024-08-01 22:05:18 +03:00
_N ( " 8580 SID " ) ,
2024-05-26 19:31:17 -05:00
_N ( " Bitwise AND " ) ,
_N ( " Bitwise OR " ) ,
_N ( " Bitwise XOR " ) ,
NULL
2024-04-21 12:59:19 -05:00
} ;
2024-04-21 13:03:03 -05:00
const char * sid2ControlBits [ 4 ] = {
2024-05-26 19:31:17 -05:00
_N ( " gate " ) ,
_N ( " sync " ) ,
_N ( " ring " ) ,
NULL
2024-04-21 13:03:03 -05:00
} ;
2024-08-05 12:28:22 +03:00
const char * sid3ControlBits [ 4 ] = {
_N ( " phase " ) ,
_N ( " sync " ) ,
_N ( " ring " ) ,
NULL
} ;
2024-08-01 22:05:18 +03:00
const char * sid3WaveMixModes [ 6 ] = {
_N ( " 8580 SID " ) ,
_N ( " Bitwise AND " ) ,
_N ( " Bitwise OR " ) ,
_N ( " Bitwise XOR " ) ,
_N ( " Sum of the signals " ) ,
NULL
} ;
2024-09-21 17:37:30 -05:00
const char * sid3SpecialWaveforms [ ] = {
2024-08-01 22:05:18 +03:00
_N ( " Sine " ) ,
_N ( " Rect. Sine " ) ,
_N ( " Abs. Sine " ) ,
_N ( " Quart. Sine " ) ,
_N ( " Squish. Sine " ) ,
_N ( " Abs. Squish. Sine " ) ,
_N ( " Rect. Saw " ) ,
_N ( " Abs. Saw " ) ,
_N ( " Cubed Saw " ) ,
_N ( " Rect. Cubed Saw " ) ,
_N ( " Abs. Cubed Saw " ) ,
_N ( " Cubed Sine " ) ,
_N ( " Rect. Cubed Sine " ) ,
_N ( " Abs. Cubed Sine " ) ,
_N ( " Quart. Cubed Sine " ) ,
_N ( " Squish. Cubed Sine " ) ,
_N ( " Squish. Abs. Cub. Sine " ) ,
_N ( " Rect. Triangle " ) ,
_N ( " Abs. Triangle " ) ,
_N ( " Quart. Triangle " ) ,
_N ( " Squish. Triangle " ) ,
_N ( " Abs. Squish. Triangle " ) ,
_N ( " Cubed Triangle " ) ,
_N ( " Rect. Cubed Triangle " ) ,
_N ( " Abs. Cubed Triangle " ) ,
_N ( " Quart. Cubed Triangle " ) ,
_N ( " Squish. Cubed Triangle " ) ,
_N ( " Squish. Abs. Cub. Triangle " ) ,
// clipped
_N ( " Clipped Sine " ) ,
_N ( " Clipped Rect. Sine " ) ,
_N ( " Clipped Abs. Sine " ) ,
_N ( " Clipped Quart. Sine " ) ,
_N ( " Clipped Squish. Sine " ) ,
_N ( " Clipped Abs. Squish. Sine " ) ,
_N ( " Clipped Rect. Saw " ) ,
_N ( " Clipped Abs. Saw " ) ,
_N ( " Clipped Cubed Saw " ) ,
_N ( " Clipped Rect. Cubed Saw " ) ,
_N ( " Clipped Abs. Cubed Saw " ) ,
_N ( " Clipped Cubed Sine " ) ,
_N ( " Clipped Rect. Cubed Sine " ) ,
_N ( " Clipped Abs. Cubed Sine " ) ,
_N ( " Clipped Quart. Cubed Sine " ) ,
_N ( " Clipped Squish. Cubed Sine " ) ,
_N ( " Clipped Squish. Abs. Cub. Sine " ) ,
_N ( " Clipped Rect. Triangle " ) ,
_N ( " Clipped Abs. Triangle " ) ,
_N ( " Clipped Quart. Triangle " ) ,
_N ( " Clipped Squish. Triangle " ) ,
_N ( " Clipped Abs. Squish. Triangle " ) ,
_N ( " Clipped Cubed Triangle " ) ,
_N ( " Clipped Rect. Cubed Triangle " ) ,
_N ( " Clipped Abs. Cubed Triangle " ) ,
_N ( " Clipped Quart. Cubed Triangle " ) ,
_N ( " Clipped Squish. Cubed Triangle " ) ,
_N ( " Clipped Squish. Abs. Cub. Triangle " ) ,
// two clipped simple waves
_N ( " Clipped Triangle " ) ,
_N ( " Clipped Saw " )
} ;
2022-04-12 18:26:25 -05:00
const bool opIsOutput [ 8 ] [ 4 ] = {
{ false , false , false , true } ,
{ false , false , false , true } ,
{ false , false , false , true } ,
{ false , false , false , true } ,
{ false , true , false , true } ,
{ false , true , true , true } ,
{ false , true , true , true } ,
{ true , true , true , true }
} ;
const bool opIsOutputOPL [ 4 ] [ 4 ] = {
{ false , false , false , true } ,
{ true , false , false , true } ,
{ false , true , false , true } ,
{ true , false , true , true }
} ;
2022-02-17 13:08:17 -05:00
enum FMParams {
FM_ALG = 0 ,
FM_FB = 1 ,
FM_FMS = 2 ,
FM_AMS = 3 ,
FM_AR = 4 ,
FM_DR = 5 ,
FM_D2R = 6 ,
FM_RR = 7 ,
FM_SL = 8 ,
FM_TL = 9 ,
FM_RS = 10 ,
FM_MULT = 11 ,
FM_DT = 12 ,
FM_DT2 = 13 ,
FM_SSG = 14 ,
2022-02-26 03:27:37 -05:00
FM_AM = 15 ,
FM_DAM = 16 ,
FM_DVB = 17 ,
FM_EGT = 18 ,
FM_EGS = 19 ,
FM_KSL = 20 ,
FM_SUS = 21 ,
FM_VIB = 22 ,
FM_WS = 23 ,
FM_KSR = 24 ,
FM_DC = 25 ,
2022-04-07 00:45:53 -05:00
FM_DM = 26 ,
FM_EGSHIFT = 27 ,
FM_REV = 28 ,
FM_FINE = 29 ,
FM_FMS2 = 30 ,
2024-09-18 14:48:10 +07:00
FM_AMS2 = 31 ,
FM_BLOCK = 32
2022-02-17 13:08:17 -05:00
} ;
2023-10-14 08:10:37 -03:00
enum ESFMParams {
ESFM_NOISE = 0 ,
ESFM_DELAY = 1 ,
ESFM_OUTLVL = 2 ,
ESFM_MODIN = 3 ,
ESFM_LEFT = 4 ,
ESFM_RIGHT = 5 ,
ESFM_CT = 6 ,
2023-10-15 19:46:07 -03:00
ESFM_DT = 7 ,
ESFM_FIXED = 8
2023-10-14 08:10:37 -03:00
} ;
2024-05-26 19:31:17 -05:00
# define FM_NAME(x) _(fmParamNames[settings.fmNames][x])
2022-03-27 03:29:45 -05:00
# define FM_SHORT_NAME(x) fmParamShortNames[settings.fmNames][x]
2024-05-26 19:31:17 -05:00
# define ESFM_LONG_NAME(x) _(esfmParamLongNames[x])
# define ESFM_NAME(x) _(esfmParamNames[x])
2023-10-14 08:10:37 -03:00
# define ESFM_SHORT_NAME(x) (esfmParamShortNames[x])
2022-02-17 13:08:17 -05:00
2022-10-07 04:11:45 -05:00
const char * macroTypeLabels [ 4 ] = {
ICON_FA_BAR_CHART " ##IMacroType " ,
2023-10-28 19:15:32 -05:00
ICON_FUR_ADSR " ##IMacroType " ,
ICON_FUR_TRI " ##IMacroType " ,
2022-10-07 04:11:45 -05:00
ICON_FA_SIGN_OUT " ##IMacroType "
} ;
2022-10-07 16:47:18 -05:00
const char * macroLFOShapes [ 4 ] = {
2024-05-26 19:31:17 -05:00
_N ( " Triangle " ) ,
_N ( " Saw " ) ,
_N ( " Square " ) ,
_N ( " How did you even " )
2022-10-07 16:47:18 -05:00
} ;
2022-04-10 18:36:04 +09:00
const char * fmOperatorBits [ 5 ] = {
2022-04-10 16:52:03 -05:00
" op1 " , " op2 " , " op3 " , " op4 " , NULL
2022-04-10 18:36:04 +09:00
} ;
2022-02-17 13:08:17 -05:00
const char * c64ShapeBits [ 5 ] = {
2024-05-26 19:31:17 -05:00
_N ( " triangle " ) ,
_N ( " saw " ) ,
_N ( " pulse " ) ,
_N ( " noise " ) ,
NULL
2022-02-17 13:08:17 -05:00
} ;
const char * ayShapeBits [ 4 ] = {
2024-05-26 19:31:17 -05:00
_N ( " tone " ) ,
_N ( " noise " ) ,
_N ( " envelope " ) ,
NULL
2022-02-17 13:08:17 -05:00
} ;
2024-08-05 12:28:22 +03:00
const char * sid3ShapeBits [ 6 ] = {
_N ( " triangle " ) ,
_N ( " saw " ) ,
_N ( " pulse " ) ,
_N ( " noise " ) ,
_N ( " special wave " ) ,
NULL
} ;
2024-08-06 16:43:24 +03:00
const char * sid3FilterMatrixBits [ 5 ] = {
2024-08-18 18:55:46 +03:00
_N ( " From filter 1 " ) ,
_N ( " From filter 2 " ) ,
_N ( " From filter 3 " ) ,
_N ( " From filter 4 " ) ,
2024-08-06 16:43:24 +03:00
NULL
} ;
2022-02-17 13:08:17 -05:00
const char * ayEnvBits [ 4 ] = {
2024-05-26 19:31:17 -05:00
_N ( " hold " ) ,
_N ( " alternate " ) ,
_N ( " direction " ) ,
_N ( " enable " )
2022-02-17 13:08:17 -05:00
} ;
const char * ssgEnvBits [ 5 ] = {
2024-05-26 19:31:17 -05:00
" 0 " , " 1 " , " 2 " , _N ( " enabled " ) , NULL
2022-02-17 13:08:17 -05:00
} ;
const char * saaEnvBits [ 9 ] = {
2024-05-26 19:31:17 -05:00
_N ( " mirror " ) ,
_N ( " loop " ) ,
_N ( " cut " ) ,
_N ( " direction " ) ,
_N ( " resolution " ) ,
_N ( " fixed " ) ,
_N ( " N/A " ) ,
_N ( " enabled " ) ,
NULL
2022-02-17 13:08:17 -05:00
} ;
2022-09-25 03:33:39 -05:00
const char * snesModeBits [ 6 ] = {
2024-05-26 19:31:17 -05:00
_N ( " noise " ) ,
_N ( " echo " ) ,
_N ( " pitch mod " ) ,
_N ( " invert right " ) ,
_N ( " invert left " ) ,
NULL
2022-09-25 03:33:39 -05:00
} ;
2022-02-17 13:08:17 -05:00
const char * filtModeBits [ 5 ] = {
2024-05-26 19:31:17 -05:00
_N ( " low " ) ,
_N ( " band " ) ,
_N ( " high " ) ,
_N ( " ch3off " ) ,
NULL
2022-02-17 13:08:17 -05:00
} ;
2023-10-29 01:39:37 -05:00
const char * c64TestGateBits [ 5 ] = {
2024-05-26 19:31:17 -05:00
_N ( " gate " ) ,
_N ( " sync " ) ,
_N ( " ring " ) ,
_N ( " test " ) ,
NULL
2022-02-17 13:08:17 -05:00
} ;
2022-12-20 02:59:26 -05:00
const char * pokeyCtlBits [ 9 ] = {
2024-05-26 19:31:17 -05:00
_N ( " 15KHz " ) ,
_N ( " filter 2+4 " ) ,
_N ( " filter 1+3 " ) ,
_N ( " 16-bit 3+4 " ) ,
_N ( " 16-bit 1+2 " ) ,
_N ( " high3 " ) ,
_N ( " high1 " ) ,
_N ( " poly9 " ) ,
NULL
2022-12-20 02:59:26 -05:00
} ;
2024-09-21 17:37:30 -05:00
const char * mikeyFeedbackBits [ 11 ] = {
2022-02-20 18:15:15 +01:00
" 0 " , " 1 " , " 2 " , " 3 " , " 4 " , " 5 " , " 7 " , " 10 " , " 11 " , " int " , NULL
} ;
2022-10-01 19:47:40 -05:00
const char * msm5232ControlBits [ 7 ] = {
2024-05-26 19:31:17 -05:00
_N ( " 16' " ) ,
_N ( " 8' " ) ,
_N ( " 4' " ) ,
_N ( " 2' " ) ,
_N ( " sustain " ) ,
NULL
2022-10-01 03:15:40 -05:00
} ;
2023-07-23 04:42:38 -05:00
const char * tedControlBits [ 3 ] = {
2024-05-26 19:31:17 -05:00
_N ( " square " ) ,
_N ( " noise " ) ,
NULL
2023-07-23 04:42:38 -05:00
} ;
2023-08-28 17:59:34 -05:00
const char * c219ControlBits [ 4 ] = {
2024-05-26 19:31:17 -05:00
_N ( " noise " ) ,
_N ( " invert " ) ,
_N ( " surround " ) ,
NULL
2023-08-28 17:59:34 -05:00
} ;
2022-03-09 00:50:10 +09:00
const char * x1_010EnvBits [ 8 ] = {
2024-05-26 19:31:17 -05:00
_N ( " enable " ) ,
_N ( " oneshot " ) ,
_N ( " split L/R " ) ,
_N ( " HinvR " ) ,
_N ( " VinvR " ) ,
_N ( " HinvL " ) ,
_N ( " VinvL " ) ,
NULL
2022-03-07 02:31:03 +09:00
} ;
2022-04-27 04:48:56 -05:00
const char * suControlBits [ 5 ] = {
2024-05-26 19:31:17 -05:00
_N ( " ring mod " ) ,
_N ( " low pass " ) ,
_N ( " high pass " ) ,
_N ( " band pass " ) ,
NULL
2022-04-27 04:48:56 -05:00
} ;
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
const char * es5506FilterModes [ 4 ] = {
" HP/K2, HP/K2 " , " HP/K2, LP/K1 " , " LP/K2, LP/K2 " , " LP/K2, LP/K1 " ,
} ;
2024-01-24 13:14:49 -05:00
const char * powerNoiseControlBits [ 3 ] = {
2024-05-26 19:31:17 -05:00
_N ( " enable tap B " ) ,
_N ( " AM with slope " ) ,
NULL
2024-01-24 04:52:27 -05:00
} ;
const char * powerNoiseSlopeControlBits [ 7 ] = {
2024-05-26 19:31:17 -05:00
_N ( " invert B " ) ,
_N ( " invert A " ) ,
_N ( " reset B " ) ,
_N ( " reset A " ) ,
_N ( " clip B " ) ,
_N ( " clip A " ) ,
NULL
2024-01-23 11:05:50 -05:00
} ;
2024-02-04 02:05:00 -05:00
const char * daveControlBits [ 5 ] = {
2024-05-26 19:31:17 -05:00
_N ( " high pass " ) ,
_N ( " ring mod " ) ,
_N ( " swap counters (noise) " ) ,
_N ( " low pass (noise) " ) ,
NULL
2024-02-04 02:05:00 -05:00
} ;
2023-01-04 19:16:37 -05:00
const char * panBits [ 5 ] = {
2024-05-26 19:31:17 -05:00
_N ( " right " ) ,
_N ( " left " ) ,
_N ( " rear right " ) ,
_N ( " rear left " ) ,
NULL
2022-04-16 17:24:40 -05:00
} ;
2022-02-28 18:16:05 -05:00
const char * oneBit [ 2 ] = {
2024-05-26 19:31:17 -05:00
_N ( " on " ) ,
NULL
2022-02-28 18:16:05 -05:00
} ;
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
const char * es5506EnvelopeModes [ 3 ] = {
2024-05-26 19:31:17 -05:00
_N ( " k1 slowdown " ) ,
_N ( " k2 slowdown " ) ,
NULL
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
} ;
2022-12-15 17:35:01 +09:00
const char * es5506ControlModes [ 3 ] = {
2024-05-26 19:31:17 -05:00
_N ( " pause " ) ,
_N ( " reverse " ) ,
NULL
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
} ;
2024-03-16 14:59:02 +07:00
const char * minModModeBits [ 3 ] = {
2024-05-26 19:31:17 -05:00
_N ( " invert right " ) ,
_N ( " invert left " ) ,
NULL
2024-03-16 14:59:02 +07:00
} ;
2022-02-17 13:08:17 -05:00
const int orderedOps [ 4 ] = {
0 , 2 , 1 , 3
} ;
2022-05-21 18:36:15 -05:00
const char * singleWSEffects [ 7 ] = {
2024-05-26 19:31:17 -05:00
_N ( " None " ) ,
_N ( " Invert " ) ,
_N ( " Add " ) ,
_N ( " Subtract " ) ,
_N ( " Average " ) ,
_N ( " Phase " ) ,
_N ( " Chorus " )
2022-04-07 18:27:17 -05:00
} ;
2022-05-21 18:36:15 -05:00
const char * dualWSEffects [ 9 ] = {
2024-05-26 19:31:17 -05:00
_N ( " None (dual) " ) ,
_N ( " Wipe " ) ,
_N ( " Fade " ) ,
_N ( " Fade (ping-pong) " ) ,
_N ( " Overlay " ) ,
_N ( " Negative Overlay " ) ,
_N ( " Slide " ) ,
_N ( " Mix Chorus " ) ,
_N ( " Phase Modulation " )
2022-04-07 18:27:17 -05:00
} ;
2022-08-07 06:06:14 -05:00
const char * gbHWSeqCmdTypes [ 6 ] = {
2024-05-26 19:31:17 -05:00
_N ( " Envelope " ) ,
_N ( " Sweep " ) ,
_N ( " Wait " ) ,
_N ( " Wait for Release " ) ,
_N ( " Loop " ) ,
_N ( " Loop until Release " )
2022-04-10 14:01:55 +09:00
} ;
2022-05-11 00:16:20 +09:00
2023-10-21 18:42:37 -05:00
const char * suHWSeqCmdTypes [ 7 ] = {
2024-05-26 19:31:17 -05:00
_N ( " Volume Sweep " ) ,
_N ( " Frequency Sweep " ) ,
_N ( " Cutoff Sweep " ) ,
_N ( " Wait " ) ,
_N ( " Wait for Release " ) ,
_N ( " Loop " ) ,
_N ( " Loop until Release " )
2023-10-21 18:42:37 -05:00
} ;
2022-09-18 17:59:58 +07:00
const char * snesGainModes [ 5 ] = {
2024-05-26 19:31:17 -05:00
_N ( " Direct " ) ,
_N ( " Decrease (linear) " ) ,
_N ( " Decrease (logarithmic) " ) ,
_N ( " Increase (linear) " ) ,
_N ( " Increase (bent line) " )
2022-04-10 14:01:55 +09:00
} ;
2022-05-11 00:16:20 +09:00
2022-11-15 16:09:24 -05:00
const int detuneMap [ 2 ] [ 8 ] = {
{ - 3 , - 2 , - 1 , 0 , 1 , 2 , 3 , 4 } ,
{ 7 , 6 , 5 , 0 , 1 , 2 , 3 , 4 }
} ;
const int detuneUnmap [ 2 ] [ 11 ] = {
{ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 3 , 4 , 5 , 6 , 7 , 2 , 1 , 0 }
} ;
2023-01-15 14:12:23 -05:00
const int kslMap [ 4 ] = {
0 , 2 , 1 , 3
} ;
2024-09-21 17:37:30 -05:00
const int _SID3_SPECIAL_WAVES = SID3_NUM_SPECIAL_WAVES - 1 ;
const int _SID3_NUM_CHANNELS = SID3_NUM_CHANNELS ;
const int _SID3_NUM_CHANNELS_MINUS_ONE = SID3_NUM_CHANNELS - 1 ;
2022-08-18 18:21:51 -05:00
// do not change these!
// anything other than a checkbox will look ugly!
//
// if you really need to, and have a good rationale (and by good I mean a VERY
// good one), please tell me and we'll sort it out.
2022-04-28 01:31:16 -05:00
const char * macroAbsoluteMode = " Fixed " ;
const char * macroRelativeMode = " Relative " ;
2022-04-28 23:58:11 -05:00
const char * macroQSoundMode = " QSound " ;
2022-04-28 01:31:16 -05:00
const char * macroDummyMode = " Bug " ;
2022-04-10 14:01:55 +09:00
2022-09-09 16:41:00 -05:00
String macroHoverNote ( int id , float val , void * u ) {
int * macroVal = ( int * ) u ;
if ( ( macroVal [ id ] & 0xc0000000 ) = = 0x40000000 | | ( macroVal [ id ] & 0xc0000000 ) = = 0x80000000 ) {
if ( val < - 60 | | val > = 120 ) return " ??? " ;
return fmt : : sprintf ( " %d: %s " , id , noteNames [ ( int ) val + 60 ] ) ;
}
return fmt : : sprintf ( " %d: %d " , id , ( int ) val ) ;
2022-02-17 13:08:17 -05:00
}
2022-09-09 16:41:00 -05:00
String macroHover ( int id , float val , void * u ) {
2022-10-03 18:40:07 -05:00
return fmt : : sprintf ( " %d: %d " , id , ( int ) val ) ;
2022-02-17 13:08:17 -05:00
}
2022-09-09 16:41:00 -05:00
String macroHoverLoop ( int id , float val , void * u ) {
2024-05-26 19:31:17 -05:00
if ( val > 1 ) return _ ( " Release " ) ;
if ( val > 0 ) return _ ( " Loop " ) ;
2022-02-17 13:08:17 -05:00
return " " ;
}
2022-09-09 16:41:00 -05:00
String macroHoverBit30 ( int id , float val , void * u ) {
2024-05-26 19:31:17 -05:00
if ( val > 0 ) return _ ( " Fixed " ) ;
return _ ( " Relative " ) ;
2022-02-17 13:08:17 -05:00
}
2022-10-03 18:40:07 -05:00
String macroHoverGain ( int id , float val , void * u ) {
if ( val > = 224.0f ) {
2024-05-26 19:31:17 -05:00
return fmt : : sprintf ( _ ( " %d: +%d (exponential) " ) , id , ( int ) ( val - 224 ) ) ;
2022-10-03 18:40:07 -05:00
}
if ( val > = 192.0f ) {
2024-05-26 19:31:17 -05:00
return fmt : : sprintf ( _ ( " %d: +%d (linear) " ) , id , ( int ) ( val - 192 ) ) ;
2022-10-03 18:40:07 -05:00
}
if ( val > = 160.0f ) {
2024-05-26 19:31:17 -05:00
return fmt : : sprintf ( _ ( " %d: -%d (exponential) " ) , id , ( int ) ( val - 160 ) ) ;
2022-10-03 18:40:07 -05:00
}
if ( val > = 128.0f ) {
2024-05-26 19:31:17 -05:00
return fmt : : sprintf ( _ ( " %d: -%d (linear) " ) , id , ( int ) ( val - 128 ) ) ;
2022-10-03 18:40:07 -05:00
}
2024-05-26 19:31:17 -05:00
return fmt : : sprintf ( _ ( " %d: %d (direct) " ) , id , ( int ) val ) ;
2022-10-03 18:40:07 -05:00
}
2022-09-09 16:41:00 -05:00
String macroHoverES5506FilterMode ( int id , float val , void * u ) {
2022-05-11 00:16:20 +09:00
String mode = " ??? " ;
2022-04-26 12:04:23 +09:00
switch ( ( ( int ) val ) & 3 ) {
case 0 :
2024-08-17 13:40:15 +03:00
mode = _ ( " HP/K2, HP/K2 " ) ;
2022-05-11 00:16:20 +09:00
break ;
2022-04-26 12:04:23 +09:00
case 1 :
2024-08-17 13:40:15 +03:00
mode = _ ( " HP/K2, LP/K1 " ) ;
2022-05-11 00:16:20 +09:00
break ;
2022-04-26 12:04:23 +09:00
case 2 :
2024-08-17 13:40:15 +03:00
mode = _ ( " LP/K2, LP/K2 " ) ;
2022-05-11 00:16:20 +09:00
break ;
2022-04-26 12:04:23 +09:00
case 3 :
2024-08-17 13:40:15 +03:00
mode = _ ( " LP/K2, LP/K1 " ) ;
2022-05-11 00:16:20 +09:00
break ;
2022-04-26 12:04:23 +09:00
default :
2022-05-11 00:16:20 +09:00
break ;
2022-04-26 12:04:23 +09:00
}
2022-05-11 00:16:20 +09:00
return fmt : : sprintf ( " %d: %s " , id , mode ) ;
2022-04-26 12:04:23 +09:00
}
2022-09-09 16:41:00 -05:00
String macroLFOWaves ( int id , float val , void * u ) {
2025-07-23 11:04:39 +04:00
const char * label = " ??? " ;
2022-02-17 13:08:17 -05:00
switch ( ( ( int ) val ) & 3 ) {
case 0 :
2025-07-23 11:04:39 +04:00
label = _ ( " Saw " ) ;
break ;
2022-02-17 13:08:17 -05:00
case 1 :
2025-07-23 11:04:39 +04:00
label = _ ( " Square " ) ;
break ;
2022-02-17 13:08:17 -05:00
case 2 :
2025-07-23 11:04:39 +04:00
label = _ ( " Triangle " ) ;
break ;
2022-02-17 13:08:17 -05:00
case 3 :
2025-07-23 11:04:39 +04:00
label = _ ( " Random " ) ;
break ;
default : break ;
2022-02-17 13:08:17 -05:00
}
2025-07-23 11:04:39 +04:00
return fmt : : sprintf ( " %d: %s " , id , label ) ;
2022-02-17 13:08:17 -05:00
}
2025-06-28 00:54:45 +04:00
String macroVERAWaves ( int id , float val , void * u ) {
2025-07-23 11:04:39 +04:00
const char * label = " ??? " ;
2025-06-28 00:54:45 +04:00
switch ( ( ( int ) val ) & 3 ) {
case 0 :
2025-07-23 11:04:39 +04:00
label = _ ( " Pulse " ) ;
break ;
2025-06-28 00:54:45 +04:00
case 1 :
2025-07-23 11:04:39 +04:00
label = _ ( " Saw " ) ;
break ;
2025-06-28 00:54:45 +04:00
case 2 :
2025-07-23 11:04:39 +04:00
label = _ ( " Triangle " ) ;
break ;
2025-06-28 00:54:45 +04:00
case 3 :
2025-07-23 11:04:39 +04:00
label = _ ( " Noise " ) ;
break ;
default : break ;
2025-06-28 00:54:45 +04:00
}
2025-07-23 11:04:39 +04:00
return fmt : : sprintf ( " %d: %s " , id , label ) ;
2025-06-28 00:54:45 +04:00
}
String macroSoundUnitWaves ( int id , float val , void * u ) {
2025-07-23 11:04:39 +04:00
const char * label = " ??? " ;
2025-06-28 00:54:45 +04:00
switch ( ( ( int ) val ) & 7 ) {
case 0 :
2025-07-23 11:04:39 +04:00
label = _ ( " Square " ) ;
break ;
2025-06-28 00:54:45 +04:00
case 1 :
2025-07-23 11:04:39 +04:00
label = _ ( " Saw " ) ;
break ;
2025-06-28 00:54:45 +04:00
case 2 :
2025-07-23 11:04:39 +04:00
label = _ ( " Sine " ) ;
break ;
2025-06-28 00:54:45 +04:00
case 3 :
2025-07-23 11:04:39 +04:00
label = _ ( " Triangle " ) ;
break ;
2025-06-28 00:54:45 +04:00
case 4 :
2025-07-23 11:04:39 +04:00
label = _ ( " Noise " ) ;
break ;
2025-06-28 00:54:45 +04:00
case 5 :
2025-07-23 11:04:39 +04:00
label = _ ( " Short Noise " ) ;
break ;
2025-06-28 00:54:45 +04:00
case 6 :
2025-07-23 11:04:39 +04:00
label = _ ( " XOR Sine " ) ;
break ;
2025-06-28 00:54:45 +04:00
case 7 :
2025-07-23 11:04:39 +04:00
label = _ ( " XOR Triangle " ) ;
break ;
default : break ;
2025-06-28 00:54:45 +04:00
}
2025-07-23 11:04:39 +04:00
return fmt : : sprintf ( " %d: %s " , id , label ) ;
2025-06-28 00:54:45 +04:00
}
2025-10-04 18:39:07 -05:00
String macroTFXModes ( int id , float val , void * u ) {
switch ( ( ( int ) val ) & 3 ) {
case 0 :
return _ ( " Disabled " ) ;
case 1 :
return _ ( " PWM " ) ;
case 2 :
return _ ( " SyncBuzzer " ) ;
case 3 :
return _ ( " Reserved " ) ;
default :
return " ??? " ;
}
return " ??? " ;
}
2024-09-21 17:37:30 -05:00
String macroSID3SpecialWaves ( int id , float val , void * u ) {
if ( ( int ) val < 0 | | ( int ) val > = SID3_NUM_SPECIAL_WAVES ) return " ??? " ;
2024-08-05 12:28:22 +03:00
2025-07-23 11:04:39 +04:00
return fmt : : sprintf ( " %d: %s " , id , _ ( sid3SpecialWaveforms [ ( int ) val % SID3_NUM_SPECIAL_WAVES ] ) ) ;
2024-08-05 12:28:22 +03:00
}
2024-09-21 17:37:30 -05:00
String macroSID3SourceChan ( int id , float val , void * u ) {
if ( ( int ) val > SID3_NUM_CHANNELS ) return " ??? " ;
2024-08-05 12:28:22 +03:00
2024-09-21 17:37:30 -05:00
if ( ( int ) val = = SID3_NUM_CHANNELS ) {
2024-08-05 12:28:22 +03:00
return _ ( " Self " ) ;
2024-09-21 17:37:30 -05:00
} else if ( ( int ) val = = SID3_NUM_CHANNELS - 1 ) {
2024-08-05 12:28:22 +03:00
return _ ( " PCM/Wave channel " ) ;
2024-09-21 17:37:30 -05:00
} else {
return fmt : : sprintf ( _ ( " Channel %d " ) , ( int ) val + 1 ) ;
2024-08-05 12:28:22 +03:00
}
}
2024-09-21 17:37:30 -05:00
String macroSID3NoiseLFSR ( int id , float val , void * u ) {
return _ (
" values close to SID2 noise modes: \n \n "
" Mode 1: 524288 \n "
" Mode 2: 66 \n "
" Mode 3: 541065280 "
) ;
2024-08-17 13:40:15 +03:00
}
2024-09-21 17:37:30 -05:00
String macroSID2WaveMixMode ( int id , float val , void * u ) {
if ( ( int ) val < 0 | | ( int ) val > 3 ) return " ??? " ;
2024-08-10 14:21:28 +03:00
2025-07-23 11:04:39 +04:00
return fmt : : sprintf ( " %d: %s " , id , _ ( sid2WaveMixModes [ ( int ) val ] ) ) ;
2024-08-10 14:21:28 +03:00
}
2024-09-21 17:37:30 -05:00
String macroSID3WaveMixMode ( int id , float val , void * u ) {
if ( ( int ) val < 0 | | ( int ) val > 4 ) return " ??? " ;
2024-08-05 12:28:22 +03:00
2025-07-23 11:04:39 +04:00
return fmt : : sprintf ( " %d: %s " , id , _ ( sid3WaveMixModes [ ( int ) val ] ) ) ;
2024-08-05 12:28:22 +03:00
}
2022-02-28 18:16:05 -05:00
void addAALine ( ImDrawList * dl , const ImVec2 & p1 , const ImVec2 & p2 , const ImU32 color , float thickness = 1.0f ) {
ImVec2 pt [ 2 ] ;
pt [ 0 ] = p1 ;
pt [ 1 ] = p2 ;
dl - > AddPolyline ( pt , 2 , color , ImDrawFlags_None , thickness ) ;
}
2022-03-27 03:29:45 -05:00
void FurnaceGUI : : drawSSGEnv ( unsigned char type , const ImVec2 & size ) {
ImDrawList * dl = ImGui : : GetWindowDrawList ( ) ;
ImGuiWindow * window = ImGui : : GetCurrentWindow ( ) ;
ImVec2 minArea = window - > DC . CursorPos ;
ImVec2 maxArea = ImVec2 (
minArea . x + size . x ,
minArea . y + size . y
) ;
ImRect rect = ImRect ( minArea , maxArea ) ;
ImGuiStyle & style = ImGui : : GetStyle ( ) ;
2022-04-12 18:26:25 -05:00
ImU32 color = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_SSG ] ) ;
2022-03-27 03:29:45 -05:00
ImGui : : ItemSize ( size , style . FramePadding . y ) ;
if ( ImGui : : ItemAdd ( rect , ImGui : : GetID ( " ssgEnvDisplay " ) ) ) {
ImGui : : RenderFrame ( rect . Min , rect . Max , ImGui : : GetColorU32 ( ImGuiCol_FrameBg ) , true , style . FrameRounding ) ;
switch ( type ) {
case 0 :
for ( int i = 0 ; i < 4 ; i + + ) {
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( ( float ) i / 4.0f , 0.2 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( ( float ) ( i + 1 ) / 4.0f , 0.8 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
pos1 . x = pos2 . x ;
if ( i < 3 ) addAALine ( dl , pos1 , pos2 , color ) ;
}
break ;
case 1 : {
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.0 , 0.2 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.8 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 1.0 , 0.8 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
break ;
}
case 2 : {
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.0 , 0.2 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.8 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.2 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.75 , 0.8 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 1.0 , 0.2 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
break ;
}
case 3 : {
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.0 , 0.2 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.8 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
pos1 . x = pos2 . x ;
addAALine ( dl , pos1 , pos2 , color ) ;
pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 1.0 , 0.2 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
break ;
}
case 4 :
for ( int i = 0 ; i < 4 ; i + + ) {
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( ( float ) i / 4.0f , 0.8 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( ( float ) ( i + 1 ) / 4.0f , 0.2 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
pos1 . x = pos2 . x ;
if ( i < 3 ) addAALine ( dl , pos1 , pos2 , color ) ;
}
break ;
case 5 : {
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.0 , 0.8 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.2 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 1.0 , 0.2 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
break ;
}
case 6 : {
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.0 , 0.8 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.2 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.8 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.75 , 0.2 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 1.0 , 0.8 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
break ;
}
case 7 : {
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.0 , 0.8 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.2 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
pos1 . x = pos2 . x ;
addAALine ( dl , pos1 , pos2 , color ) ;
pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 1.0 , 0.8 ) ) ;
addAALine ( dl , pos1 , pos2 , color ) ;
break ;
}
}
}
}
void FurnaceGUI : : drawWaveform ( unsigned char type , bool opz , const ImVec2 & size ) {
2022-03-27 18:30:46 -05:00
ImDrawList * dl = ImGui : : GetWindowDrawList ( ) ;
ImGuiWindow * window = ImGui : : GetCurrentWindow ( ) ;
ImVec2 waveform [ 65 ] ;
const size_t waveformLen = 64 ;
2022-03-27 03:29:45 -05:00
2022-03-27 18:30:46 -05:00
ImVec2 minArea = window - > DC . CursorPos ;
ImVec2 maxArea = ImVec2 (
minArea . x + size . x ,
minArea . y + size . y
) ;
ImRect rect = ImRect ( minArea , maxArea ) ;
ImGuiStyle & style = ImGui : : GetStyle ( ) ;
2022-04-12 18:26:25 -05:00
ImU32 color = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_WAVE ] ) ;
2022-03-27 18:30:46 -05:00
ImGui : : ItemSize ( size , style . FramePadding . y ) ;
if ( ImGui : : ItemAdd ( rect , ImGui : : GetID ( " wsDisplay " ) ) ) {
ImGui : : RenderFrame ( rect . Min , rect . Max , ImGui : : GetColorU32 ( ImGuiCol_FrameBg ) , true , style . FrameRounding ) ;
2022-04-07 00:45:53 -05:00
if ( opz ) {
switch ( type ) {
case 0 :
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
float x = ( float ) i / ( float ) waveformLen ;
float y = sin ( x * 2.0 * M_PI ) ;
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
break ;
case 1 :
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
float x = ( float ) i / ( float ) waveformLen ;
float y = pow ( sin ( x * 2.0 * M_PI ) , 2.0 ) ;
if ( x > = 0.5 ) y = - y ;
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
break ;
case 2 :
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
float x = ( float ) i / ( float ) waveformLen ;
float y = MAX ( 0.0 , sin ( x * 2.0 * M_PI ) ) ;
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
break ;
case 3 :
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
float x = ( float ) i / ( float ) waveformLen ;
float y = pow ( MAX ( 0.0 , sin ( x * 2.0 * M_PI ) ) , 2.0 ) ;
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
break ;
case 4 :
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
float x = ( float ) i / ( float ) waveformLen ;
float y = ( x > = 0.5 ) ? 0.0 : sin ( x * 4.0 * M_PI ) ;
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
break ;
case 5 :
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
float x = ( float ) i / ( float ) waveformLen ;
float y = ( x > = 0.5 ) ? 0.0 : pow ( sin ( x * 4.0 * M_PI ) , 2.0 ) ;
if ( x > = 0.25 ) y = - y ;
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
break ;
case 6 :
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
float x = ( float ) i / ( float ) waveformLen ;
float y = ( x > = 0.5 ) ? 0.0 : fabs ( sin ( x * 4.0 * M_PI ) ) ;
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
break ;
case 7 :
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
float x = ( float ) i / ( float ) waveformLen ;
float y = ( x > = 0.5 ) ? 0.0 : pow ( sin ( x * 4.0 * M_PI ) , 2.0 ) ;
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
break ;
}
} else {
switch ( type ) {
case 0 :
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
float x = ( float ) i / ( float ) waveformLen ;
float y = sin ( x * 2.0 * M_PI ) ;
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
break ;
case 1 :
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
float x = ( float ) i / ( float ) waveformLen ;
float y = MAX ( 0.0 , sin ( x * 2.0 * M_PI ) ) ;
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
break ;
case 2 :
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
float x = ( float ) i / ( float ) waveformLen ;
float y = fabs ( sin ( x * 2.0 * M_PI ) ) ;
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
break ;
case 3 :
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
float x = ( float ) i / ( float ) waveformLen ;
float y = fabs ( ( tan ( x * 2.0 * M_PI ) > = 0.0 ) ? sin ( x * 2.0 * M_PI ) : 0.0 ) ;
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
break ;
case 4 :
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
float x = ( float ) i / ( float ) waveformLen ;
float y = ( x > = 0.5 ) ? 0.0 : sin ( x * 4.0 * M_PI ) ;
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
break ;
case 5 :
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
float x = ( float ) i / ( float ) waveformLen ;
float y = ( x > = 0.5 ) ? 0.0 : fabs ( sin ( x * 4.0 * M_PI ) ) ;
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
break ;
case 6 :
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
float x = ( float ) i / ( float ) waveformLen ;
float y = ( x > = 0.5 ) ? - 1.0 : 1.0 ;
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
break ;
case 7 :
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
float x = ( float ) i / ( float ) waveformLen ;
float y = pow ( 2.0 * ( x - 0.5 ) , 3.0 ) ;
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
break ;
}
2022-03-27 18:30:46 -05:00
}
dl - > AddPolyline ( waveform , waveformLen + 1 , color , ImDrawFlags_None , dpiScale ) ;
}
2022-03-27 03:29:45 -05:00
}
2024-08-01 22:05:18 +03:00
typedef double ( * WaveFunc ) ( double a ) ;
WaveFunc waveFuncsIns [ ] = {
sinus ,
rectSin ,
absSin ,
quartSin ,
squiSin ,
squiAbsSin ,
rectSaw ,
absSaw ,
cubSaw ,
rectCubSaw ,
absCubSaw ,
cubSine ,
rectCubSin ,
absCubSin ,
quartCubSin ,
squishCubSin ,
squishAbsCubSin ,
rectTri ,
absTri ,
quartTri ,
squiTri ,
absSquiTri ,
cubTriangle ,
cubRectTri ,
cubAbsTri ,
cubQuartTri ,
cubSquiTri ,
absCubSquiTri
} ;
2024-09-21 17:37:30 -05:00
void FurnaceGUI : : drawWaveformSID3 ( unsigned char type , const ImVec2 & size ) {
2024-08-01 22:05:18 +03:00
ImDrawList * dl = ImGui : : GetWindowDrawList ( ) ;
ImGuiWindow * window = ImGui : : GetCurrentWindow ( ) ;
ImVec2 waveform [ 65 ] ;
const size_t waveformLen = 64 ;
ImVec2 minArea = window - > DC . CursorPos ;
ImVec2 maxArea = ImVec2 (
minArea . x + size . x ,
minArea . y + size . y
) ;
ImRect rect = ImRect ( minArea , maxArea ) ;
ImGuiStyle & style = ImGui : : GetStyle ( ) ;
ImU32 color = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_WAVE ] ) ;
ImGui : : ItemSize ( size , style . FramePadding . y ) ;
2024-09-21 17:37:30 -05:00
if ( ImGui : : ItemAdd ( rect , ImGui : : GetID ( " SID3wsDisplay " ) ) ) {
2024-08-01 22:05:18 +03:00
ImGui : : RenderFrame ( rect . Min , rect . Max , ImGui : : GetColorU32 ( ImGuiCol_FrameBg ) , true , style . FrameRounding ) ;
2024-09-21 17:37:30 -05:00
if ( type < SID3_NUM_UNIQUE_SPECIAL_WAVES ) {
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
2024-08-01 22:05:18 +03:00
float x = ( float ) i / ( float ) waveformLen ;
2024-09-21 17:37:30 -05:00
float y = waveFuncsIns [ type ] ( x * 2.0 * M_PI ) ;
2024-08-01 22:05:18 +03:00
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
2024-09-21 17:37:30 -05:00
} else if ( type > = SID3_NUM_UNIQUE_SPECIAL_WAVES & & type < SID3_NUM_UNIQUE_SPECIAL_WAVES * 2 ) {
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
2024-08-01 22:05:18 +03:00
float x = ( float ) i / ( float ) waveformLen ;
2024-09-21 17:37:30 -05:00
float y = waveFuncsIns [ type - SID3_NUM_UNIQUE_SPECIAL_WAVES ] ( x * 2.0 * M_PI ) ;
2024-08-01 22:05:18 +03:00
2024-09-21 17:37:30 -05:00
y * = 2.0f ; // clipping
2024-08-01 22:05:18 +03:00
2024-09-21 17:37:30 -05:00
if ( y > 1.0f ) y = 1.0f ;
if ( y < - 1.0f ) y = - 1.0f ;
2024-08-01 22:05:18 +03:00
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.48 ) ) ;
}
2024-09-21 17:37:30 -05:00
} else {
if ( type = = SID3_NUM_UNIQUE_SPECIAL_WAVES * 2 ) {
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
2024-08-01 22:05:18 +03:00
float x = ( float ) i / ( float ) waveformLen ;
float y = triangle ( x * 2.0 * M_PI ) ;
2024-09-21 17:37:30 -05:00
y * = 2.0f ; // clipping
2024-08-01 22:05:18 +03:00
2024-09-21 17:37:30 -05:00
if ( y > 1.0f ) y = 1.0f ;
if ( y < - 1.0f ) y = - 1.0f ;
2024-08-01 22:05:18 +03:00
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
}
2024-09-21 17:37:30 -05:00
if ( type = = SID3_NUM_UNIQUE_SPECIAL_WAVES * 2 + 1 ) {
for ( size_t i = 0 ; i < = waveformLen ; i + + ) {
2024-08-01 22:05:18 +03:00
float x = ( float ) i / ( float ) waveformLen ;
float y = saw ( x * 2.0 * M_PI ) ;
2024-09-21 17:37:30 -05:00
y * = 2.0f ; // clipping
2024-08-01 22:05:18 +03:00
2024-09-21 17:37:30 -05:00
if ( y > 1.0f ) y = 1.0f ;
if ( y < - 1.0f ) y = - 1.0f ;
2024-08-01 22:05:18 +03:00
waveform [ i ] = ImLerp ( rect . Min , rect . Max , ImVec2 ( x , 0.5 - y * 0.4 ) ) ;
}
}
}
dl - > AddPolyline ( waveform , waveformLen + 1 , color , ImDrawFlags_None , dpiScale ) ;
}
}
2022-02-17 13:08:17 -05:00
void FurnaceGUI : : drawAlgorithm ( unsigned char alg , FurnaceGUIFMAlgs algType , const ImVec2 & size ) {
ImDrawList * dl = ImGui : : GetWindowDrawList ( ) ;
ImGuiWindow * window = ImGui : : GetCurrentWindow ( ) ;
ImVec2 minArea = window - > DC . CursorPos ;
ImVec2 maxArea = ImVec2 (
minArea . x + size . x ,
minArea . y + size . y
) ;
ImRect rect = ImRect ( minArea , maxArea ) ;
ImGuiStyle & style = ImGui : : GetStyle ( ) ;
2022-04-12 18:26:25 -05:00
ImU32 colorM = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_MOD ] ) ;
ImU32 colorC = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_CAR ] ) ;
ImU32 colorL = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_ALG_LINE ] ) ;
2022-02-17 13:08:17 -05:00
ImGui : : ItemSize ( size , style . FramePadding . y ) ;
if ( ImGui : : ItemAdd ( rect , ImGui : : GetID ( " alg " ) ) ) {
2022-04-12 18:26:25 -05:00
ImGui : : RenderFrame ( rect . Min , rect . Max , ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_ALG_BG ] ) , true , style . FrameRounding ) ;
2022-02-17 13:08:17 -05:00
const float circleRadius = 6.0f * dpiScale + 1.0f ;
switch ( algType ) {
case FM_ALGS_4OP :
switch ( alg ) {
case 0 : { // 1 > 2 > 3 > 4
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.2 , 0.5 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.4 , 0.5 ) ) ;
ImVec2 pos3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.6 , 0.5 ) ) ;
ImVec2 pos4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.8 , 0.5 ) ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos1 , 4.0f * dpiScale + 1.0f , colorM ) ;
dl - > AddCircle ( pos1 , 6.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos1 , pos2 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos2 , 4.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos2 , pos3 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos3 , 4.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos3 , pos4 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos4 , 4.0f * dpiScale + 1.0f , colorC ) ;
2022-02-17 13:08:17 -05:00
pos1 . x - = ImGui : : CalcTextSize ( " 1 " ) . x * 0.5 ;
pos2 . x - = ImGui : : CalcTextSize ( " 2 " ) . x * 0.5 ;
pos3 . x - = ImGui : : CalcTextSize ( " 3 " ) . x * 0.5 ;
pos4 . x - = ImGui : : CalcTextSize ( " 4 " ) . x * 0.5 ;
pos1 . y - = ImGui : : CalcTextSize ( " 1 " ) . y + circleRadius ;
pos2 . y - = ImGui : : CalcTextSize ( " 2 " ) . y + circleRadius ;
pos3 . y - = ImGui : : CalcTextSize ( " 3 " ) . y + circleRadius ;
pos4 . y - = ImGui : : CalcTextSize ( " 4 " ) . y + circleRadius ;
2022-04-12 18:26:25 -05:00
dl - > AddText ( pos1 , colorM , " 1 " ) ;
dl - > AddText ( pos2 , colorM , " 2 " ) ;
dl - > AddText ( pos3 , colorM , " 3 " ) ;
dl - > AddText ( pos4 , colorC , " 4 " ) ;
2022-02-17 13:08:17 -05:00
break ;
}
case 1 : { // (1+2) > 3 > 4
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.3 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.7 ) ) ;
ImVec2 pos3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.5 ) ) ;
ImVec2 pos4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.75 , 0.5 ) ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos1 , 4.0f * dpiScale + 1.0f , colorM ) ;
dl - > AddCircle ( pos1 , 6.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos1 , pos3 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos2 , 4.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos2 , pos3 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos3 , 4.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos3 , pos4 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos4 , 4.0f * dpiScale + 1.0f , colorC ) ;
2022-02-17 13:08:17 -05:00
pos2 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos1 . x = pos2 . x ;
pos3 . x - = ImGui : : CalcTextSize ( " 3 " ) . x * 0.5 ;
pos4 . x - = ImGui : : CalcTextSize ( " 4 " ) . x * 0.5 ;
pos1 . y - = ImGui : : CalcTextSize ( " 1 " ) . y * 0.5 ;
pos2 . y - = ImGui : : CalcTextSize ( " 2 " ) . y * 0.5 ;
pos3 . y - = ImGui : : CalcTextSize ( " 3 " ) . y + circleRadius ;
pos4 . y - = ImGui : : CalcTextSize ( " 4 " ) . y + circleRadius ;
2022-04-12 18:26:25 -05:00
dl - > AddText ( pos1 , colorM , " 1 " ) ;
dl - > AddText ( pos2 , colorM , " 2 " ) ;
dl - > AddText ( pos3 , colorM , " 3 " ) ;
dl - > AddText ( pos4 , colorC , " 4 " ) ;
2022-02-17 13:08:17 -05:00
break ;
}
case 2 : { // 1+(2>3) > 4
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.3 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.7 ) ) ;
ImVec2 pos3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.7 ) ) ;
ImVec2 pos4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.75 , 0.5 ) ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos1 , 4.0f * dpiScale + 1.0f , colorM ) ;
dl - > AddCircle ( pos1 , 6.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos1 , pos4 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos2 , 4.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos2 , pos3 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos3 , 4.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos3 , pos4 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos4 , 4.0f * dpiScale + 1.0f , colorC ) ;
2022-02-17 13:08:17 -05:00
pos1 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos2 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos3 . x - = ImGui : : CalcTextSize ( " 3 " ) . x + circleRadius + 3.0 * dpiScale ;
pos4 . x - = ImGui : : CalcTextSize ( " 4 " ) . x * 0.5 ;
pos1 . y - = ImGui : : CalcTextSize ( " 1 " ) . y * 0.5 ;
pos2 . y - = ImGui : : CalcTextSize ( " 2 " ) . y * 0.5 ;
pos3 . y - = ImGui : : CalcTextSize ( " 3 " ) . y * 0.5 ;
pos4 . y - = ImGui : : CalcTextSize ( " 4 " ) . y + circleRadius ;
2022-04-12 18:26:25 -05:00
dl - > AddText ( pos1 , colorM , " 1 " ) ;
dl - > AddText ( pos2 , colorM , " 2 " ) ;
dl - > AddText ( pos3 , colorM , " 3 " ) ;
dl - > AddText ( pos4 , colorC , " 4 " ) ;
2022-02-17 13:08:17 -05:00
break ;
}
case 3 : { // (1>2)+3 > 4
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.3 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.3 ) ) ;
ImVec2 pos3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.7 ) ) ;
ImVec2 pos4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.75 , 0.5 ) ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos1 , 4.0f * dpiScale + 1.0f , colorM ) ;
dl - > AddCircle ( pos1 , 6.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos1 , pos2 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos2 , 4.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos2 , pos4 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos3 , 4.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos3 , pos4 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos4 , 4.0f * dpiScale + 1.0f , colorC ) ;
2022-02-17 13:08:17 -05:00
pos1 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos2 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos3 . x - = ImGui : : CalcTextSize ( " 3 " ) . x + circleRadius + 3.0 * dpiScale ;
pos4 . x - = ImGui : : CalcTextSize ( " 4 " ) . x * 0.5 ;
pos1 . y - = ImGui : : CalcTextSize ( " 1 " ) . y * 0.5 ;
pos2 . y - = ImGui : : CalcTextSize ( " 2 " ) . y * 0.5 ;
pos3 . y - = ImGui : : CalcTextSize ( " 3 " ) . y * 0.5 ;
pos4 . y - = ImGui : : CalcTextSize ( " 4 " ) . y + circleRadius ;
2022-04-12 18:26:25 -05:00
dl - > AddText ( pos1 , colorM , " 1 " ) ;
dl - > AddText ( pos2 , colorM , " 2 " ) ;
dl - > AddText ( pos3 , colorM , " 3 " ) ;
dl - > AddText ( pos4 , colorC , " 4 " ) ;
2022-02-17 13:08:17 -05:00
break ;
}
case 4 : { // (1>2) + (3>4)
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.3 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.3 ) ) ;
ImVec2 pos3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.7 ) ) ;
ImVec2 pos4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.7 ) ) ;
ImVec2 pos5 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.75 , 0.5 ) ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos1 , 4.0f * dpiScale + 1.0f , colorM ) ;
dl - > AddCircle ( pos1 , 6.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos1 , pos2 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos2 , 4.0f * dpiScale + 1.0f , colorC ) ;
dl - > AddCircleFilled ( pos3 , 4.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos3 , pos4 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos4 , 4.0f * dpiScale + 1.0f , colorC ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos2 , pos5 , colorL ) ;
addAALine ( dl , pos4 , pos5 , colorL ) ;
2022-02-17 13:08:17 -05:00
pos1 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos2 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos3 . x - = ImGui : : CalcTextSize ( " 3 " ) . x + circleRadius + 3.0 * dpiScale ;
pos4 . x - = ImGui : : CalcTextSize ( " 4 " ) . x + circleRadius + 3.0 * dpiScale ;
pos1 . y - = ImGui : : CalcTextSize ( " 1 " ) . y * 0.5 ;
pos2 . y - = ImGui : : CalcTextSize ( " 2 " ) . y * 0.5 ;
pos3 . y - = ImGui : : CalcTextSize ( " 3 " ) . y * 0.5 ;
pos4 . y - = ImGui : : CalcTextSize ( " 4 " ) . y * 0.5 ;
2022-04-12 18:26:25 -05:00
dl - > AddText ( pos1 , colorM , " 1 " ) ;
dl - > AddText ( pos2 , colorC , " 2 " ) ;
dl - > AddText ( pos3 , colorM , " 3 " ) ;
dl - > AddText ( pos4 , colorC , " 4 " ) ;
2022-02-17 13:08:17 -05:00
break ;
}
case 5 : { // 1 > (2+3+4)
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.5 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.25 ) ) ;
ImVec2 pos3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.5 ) ) ;
ImVec2 pos4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.75 ) ) ;
ImVec2 pos5 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.75 , 0.5 ) ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos1 , 4.0f * dpiScale + 1.0f , colorM ) ;
dl - > AddCircle ( pos1 , 6.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos1 , pos2 , colorL ) ;
addAALine ( dl , pos1 , pos3 , colorL ) ;
addAALine ( dl , pos1 , pos4 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos2 , 4.0f * dpiScale + 1.0f , colorC ) ;
dl - > AddCircleFilled ( pos3 , 4.0f * dpiScale + 1.0f , colorC ) ;
dl - > AddCircleFilled ( pos4 , 4.0f * dpiScale + 1.0f , colorC ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos2 , pos5 , colorL ) ;
addAALine ( dl , pos3 , pos5 , colorL ) ;
addAALine ( dl , pos4 , pos5 , colorL ) ;
2022-02-17 13:08:17 -05:00
pos1 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos2 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos3 . x - = ImGui : : CalcTextSize ( " 3 " ) . x + circleRadius + 3.0 * dpiScale ;
pos4 . x - = ImGui : : CalcTextSize ( " 4 " ) . x + circleRadius + 3.0 * dpiScale ;
pos1 . y - = ImGui : : CalcTextSize ( " 1 " ) . y * 0.5 ;
pos2 . y - = ImGui : : CalcTextSize ( " 2 " ) . y * 0.5 ;
pos3 . y - = ImGui : : CalcTextSize ( " 3 " ) . y * 0.5 ;
pos4 . y - = ImGui : : CalcTextSize ( " 4 " ) . y * 0.5 ;
2022-04-12 18:26:25 -05:00
dl - > AddText ( pos1 , colorM , " 1 " ) ;
dl - > AddText ( pos2 , colorC , " 2 " ) ;
dl - > AddText ( pos3 , colorC , " 3 " ) ;
dl - > AddText ( pos4 , colorC , " 4 " ) ;
2022-02-17 13:08:17 -05:00
break ;
}
case 6 : { // (1>2) + 3 + 4
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.25 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.25 ) ) ;
ImVec2 pos3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.5 ) ) ;
ImVec2 pos4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.75 ) ) ;
ImVec2 pos5 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.75 , 0.5 ) ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos1 , 4.0f * dpiScale + 1.0f , colorM ) ;
dl - > AddCircle ( pos1 , 6.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos1 , pos2 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos2 , 4.0f * dpiScale + 1.0f , colorC ) ;
dl - > AddCircleFilled ( pos3 , 4.0f * dpiScale + 1.0f , colorC ) ;
dl - > AddCircleFilled ( pos4 , 4.0f * dpiScale + 1.0f , colorC ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos2 , pos5 , colorL ) ;
addAALine ( dl , pos3 , pos5 , colorL ) ;
addAALine ( dl , pos4 , pos5 , colorL ) ;
2022-02-17 13:08:17 -05:00
pos1 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos2 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos3 . x - = ImGui : : CalcTextSize ( " 3 " ) . x + circleRadius + 3.0 * dpiScale ;
pos4 . x - = ImGui : : CalcTextSize ( " 4 " ) . x + circleRadius + 3.0 * dpiScale ;
pos1 . y - = ImGui : : CalcTextSize ( " 1 " ) . y * 0.5 ;
pos2 . y - = ImGui : : CalcTextSize ( " 2 " ) . y * 0.5 ;
pos3 . y - = ImGui : : CalcTextSize ( " 3 " ) . y * 0.5 ;
pos4 . y - = ImGui : : CalcTextSize ( " 4 " ) . y * 0.5 ;
2022-04-12 18:26:25 -05:00
dl - > AddText ( pos1 , colorM , " 1 " ) ;
dl - > AddText ( pos2 , colorC , " 2 " ) ;
dl - > AddText ( pos3 , colorC , " 3 " ) ;
dl - > AddText ( pos4 , colorC , " 4 " ) ;
2022-02-17 13:08:17 -05:00
break ;
}
case 7 : { // 1 + 2 + 3 + 4
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.2 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.35 , 0.4 ) ) ;
ImVec2 pos3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.45 , 0.6 ) ) ;
ImVec2 pos4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.55 , 0.8 ) ) ;
ImVec2 pos5 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.75 , 0.5 ) ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos1 , 4.0f * dpiScale + 1.0f , colorC ) ;
dl - > AddCircle ( pos1 , 6.0f * dpiScale + 1.0f , colorC ) ;
dl - > AddCircleFilled ( pos2 , 4.0f * dpiScale + 1.0f , colorC ) ;
dl - > AddCircleFilled ( pos3 , 4.0f * dpiScale + 1.0f , colorC ) ;
dl - > AddCircleFilled ( pos4 , 4.0f * dpiScale + 1.0f , colorC ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos1 , pos5 , colorL ) ;
addAALine ( dl , pos2 , pos5 , colorL ) ;
addAALine ( dl , pos3 , pos5 , colorL ) ;
addAALine ( dl , pos4 , pos5 , colorL ) ;
2022-02-17 13:08:17 -05:00
pos1 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos2 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos3 . x - = ImGui : : CalcTextSize ( " 3 " ) . x + circleRadius + 3.0 * dpiScale ;
pos4 . x - = ImGui : : CalcTextSize ( " 4 " ) . x + circleRadius + 3.0 * dpiScale ;
pos1 . y - = ImGui : : CalcTextSize ( " 1 " ) . y * 0.5 ;
pos2 . y - = ImGui : : CalcTextSize ( " 2 " ) . y * 0.5 ;
pos3 . y - = ImGui : : CalcTextSize ( " 3 " ) . y * 0.5 ;
pos4 . y - = ImGui : : CalcTextSize ( " 4 " ) . y * 0.5 ;
2022-04-12 18:26:25 -05:00
dl - > AddText ( pos1 , colorC , " 1 " ) ;
dl - > AddText ( pos2 , colorC , " 2 " ) ;
dl - > AddText ( pos3 , colorC , " 3 " ) ;
dl - > AddText ( pos4 , colorC , " 4 " ) ;
2022-02-17 13:08:17 -05:00
break ;
}
}
break ;
2022-02-26 03:27:37 -05:00
case FM_ALGS_2OP_OPL :
switch ( alg ) {
case 0 : { // 1 > 2
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.33 , 0.5 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.67 , 0.5 ) ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos1 , 4.0f * dpiScale + 1.0f , colorM ) ;
dl - > AddCircle ( pos1 , 6.0f * dpiScale + 1.0f , colorM ) ;
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos1 , pos2 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos2 , 4.0f * dpiScale + 1.0f , colorC ) ;
2022-02-26 03:27:37 -05:00
pos1 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos2 . x + = circleRadius + 3.0 * dpiScale ;
pos1 . y - = ImGui : : CalcTextSize ( " 1 " ) . y * 0.5 ;
pos2 . y - = ImGui : : CalcTextSize ( " 2 " ) . y * 0.5 ;
2022-04-12 18:26:25 -05:00
dl - > AddText ( pos1 , colorM , " 1 " ) ;
dl - > AddText ( pos2 , colorC , " 2 " ) ;
2022-02-26 03:27:37 -05:00
break ;
}
case 1 : { // 1 + 2
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.33 , 0.5 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.67 , 0.5 ) ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos1 , 4.0f * dpiScale + 1.0f , colorC ) ;
dl - > AddCircle ( pos1 , 6.0f * dpiScale + 1.0f , colorC ) ;
dl - > AddCircleFilled ( pos2 , 4.0f * dpiScale + 1.0f , colorC ) ;
2022-02-26 03:27:37 -05:00
pos1 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos2 . x + = circleRadius + 3.0 * dpiScale ;
pos1 . y - = ImGui : : CalcTextSize ( " 1 " ) . y * 0.5 ;
pos2 . y - = ImGui : : CalcTextSize ( " 2 " ) . y * 0.5 ;
2022-04-12 18:26:25 -05:00
dl - > AddText ( pos1 , colorC , " 1 " ) ;
dl - > AddText ( pos2 , colorC , " 2 " ) ;
2022-02-26 03:27:37 -05:00
break ;
}
}
break ;
2022-03-15 00:09:45 -05:00
case FM_ALGS_4OP_OPL :
switch ( alg ) {
case 0 : { // 1 > 2 > 3 > 4
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.2 , 0.5 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.4 , 0.5 ) ) ;
ImVec2 pos3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.6 , 0.5 ) ) ;
ImVec2 pos4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.8 , 0.5 ) ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos1 , 4.0f * dpiScale + 1.0f , colorM ) ;
dl - > AddCircle ( pos1 , 6.0f * dpiScale + 1.0f , colorM ) ;
2022-03-15 00:09:45 -05:00
addAALine ( dl , pos1 , pos2 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos2 , 4.0f * dpiScale + 1.0f , colorM ) ;
2022-03-15 00:09:45 -05:00
addAALine ( dl , pos2 , pos3 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos3 , 4.0f * dpiScale + 1.0f , colorM ) ;
2022-03-15 00:09:45 -05:00
addAALine ( dl , pos3 , pos4 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos4 , 4.0f * dpiScale + 1.0f , colorC ) ;
2022-03-15 00:09:45 -05:00
pos1 . x - = ImGui : : CalcTextSize ( " 1 " ) . x * 0.5 ;
pos2 . x - = ImGui : : CalcTextSize ( " 2 " ) . x * 0.5 ;
pos3 . x - = ImGui : : CalcTextSize ( " 3 " ) . x * 0.5 ;
pos4 . x - = ImGui : : CalcTextSize ( " 4 " ) . x * 0.5 ;
pos1 . y - = ImGui : : CalcTextSize ( " 1 " ) . y + circleRadius ;
pos2 . y - = ImGui : : CalcTextSize ( " 2 " ) . y + circleRadius ;
pos3 . y - = ImGui : : CalcTextSize ( " 3 " ) . y + circleRadius ;
pos4 . y - = ImGui : : CalcTextSize ( " 4 " ) . y + circleRadius ;
2022-04-12 18:26:25 -05:00
dl - > AddText ( pos1 , colorM , " 1 " ) ;
dl - > AddText ( pos2 , colorM , " 2 " ) ;
dl - > AddText ( pos3 , colorM , " 3 " ) ;
dl - > AddText ( pos4 , colorC , " 4 " ) ;
2022-03-15 00:09:45 -05:00
break ;
}
case 1 : { // 1 + (2 > 3 > 4)
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.4 , 0.3 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.2 , 0.7 ) ) ;
ImVec2 pos3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.4 , 0.7 ) ) ;
ImVec2 pos4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.6 , 0.7 ) ) ;
ImVec2 pos5 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.8 , 0.7 ) ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos1 , 4.0f * dpiScale + 1.0f , colorC ) ;
dl - > AddCircle ( pos1 , 6.0f * dpiScale + 1.0f , colorC ) ;
2022-03-15 00:09:45 -05:00
addAALine ( dl , pos1 , pos5 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos2 , 4.0f * dpiScale + 1.0f , colorM ) ;
2022-03-15 00:09:45 -05:00
addAALine ( dl , pos2 , pos3 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos3 , 4.0f * dpiScale + 1.0f , colorM ) ;
2022-03-15 00:09:45 -05:00
addAALine ( dl , pos3 , pos4 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos4 , 4.0f * dpiScale + 1.0f , colorC ) ;
2022-03-15 00:09:45 -05:00
addAALine ( dl , pos4 , pos5 , colorL ) ;
pos1 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos2 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos3 . x - = ImGui : : CalcTextSize ( " 3 " ) . x + circleRadius + 3.0 * dpiScale ;
pos4 . x - = ImGui : : CalcTextSize ( " 4 " ) . x * 0.5 ;
pos1 . y - = ImGui : : CalcTextSize ( " 1 " ) . y * 0.5 ;
pos2 . y - = ImGui : : CalcTextSize ( " 2 " ) . y * 0.5 ;
pos3 . y - = ImGui : : CalcTextSize ( " 3 " ) . y * 0.5 ;
pos4 . y - = ImGui : : CalcTextSize ( " 4 " ) . y + circleRadius ;
2022-04-12 18:26:25 -05:00
dl - > AddText ( pos1 , colorC , " 1 " ) ;
dl - > AddText ( pos2 , colorM , " 2 " ) ;
dl - > AddText ( pos3 , colorM , " 3 " ) ;
dl - > AddText ( pos4 , colorC , " 4 " ) ;
2022-03-15 00:09:45 -05:00
break ;
}
case 2 : { // (1>2) + (3>4)
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.3 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.3 ) ) ;
ImVec2 pos3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.7 ) ) ;
ImVec2 pos4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.7 ) ) ;
ImVec2 pos5 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.75 , 0.5 ) ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos1 , 4.0f * dpiScale + 1.0f , colorM ) ;
dl - > AddCircle ( pos1 , 6.0f * dpiScale + 1.0f , colorM ) ;
2022-03-15 00:09:45 -05:00
addAALine ( dl , pos1 , pos2 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos2 , 4.0f * dpiScale + 1.0f , colorC ) ;
dl - > AddCircleFilled ( pos3 , 4.0f * dpiScale + 1.0f , colorM ) ;
2022-03-15 00:09:45 -05:00
addAALine ( dl , pos3 , pos4 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos4 , 4.0f * dpiScale + 1.0f , colorC ) ;
2022-03-15 00:09:45 -05:00
addAALine ( dl , pos2 , pos5 , colorL ) ;
addAALine ( dl , pos4 , pos5 , colorL ) ;
pos1 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos2 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos3 . x - = ImGui : : CalcTextSize ( " 3 " ) . x + circleRadius + 3.0 * dpiScale ;
pos4 . x - = ImGui : : CalcTextSize ( " 4 " ) . x + circleRadius + 3.0 * dpiScale ;
pos1 . y - = ImGui : : CalcTextSize ( " 1 " ) . y * 0.5 ;
pos2 . y - = ImGui : : CalcTextSize ( " 2 " ) . y * 0.5 ;
pos3 . y - = ImGui : : CalcTextSize ( " 3 " ) . y * 0.5 ;
pos4 . y - = ImGui : : CalcTextSize ( " 4 " ) . y * 0.5 ;
2022-04-12 18:26:25 -05:00
dl - > AddText ( pos1 , colorM , " 1 " ) ;
dl - > AddText ( pos2 , colorC , " 2 " ) ;
dl - > AddText ( pos3 , colorM , " 3 " ) ;
dl - > AddText ( pos4 , colorC , " 4 " ) ;
2022-03-15 00:09:45 -05:00
break ;
}
case 3 : { // 1 + (2 > 3) + 4
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.25 ) ) ;
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25 , 0.5 ) ) ;
ImVec2 pos3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.5 ) ) ;
ImVec2 pos4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.5 , 0.75 ) ) ;
ImVec2 pos5 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.75 , 0.5 ) ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos1 , 4.0f * dpiScale + 1.0f , colorC ) ;
dl - > AddCircle ( pos1 , 6.0f * dpiScale + 1.0f , colorC ) ;
2022-03-15 00:09:45 -05:00
addAALine ( dl , pos2 , pos3 , colorL ) ;
2022-04-12 18:26:25 -05:00
dl - > AddCircleFilled ( pos2 , 4.0f * dpiScale + 1.0f , colorM ) ;
dl - > AddCircleFilled ( pos3 , 4.0f * dpiScale + 1.0f , colorC ) ;
dl - > AddCircleFilled ( pos4 , 4.0f * dpiScale + 1.0f , colorC ) ;
2022-03-15 00:09:45 -05:00
addAALine ( dl , pos1 , pos5 , colorL ) ;
addAALine ( dl , pos3 , pos5 , colorL ) ;
addAALine ( dl , pos4 , pos5 , colorL ) ;
pos1 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos2 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0 * dpiScale ;
pos3 . x - = ImGui : : CalcTextSize ( " 3 " ) . x + circleRadius + 3.0 * dpiScale ;
pos4 . x - = ImGui : : CalcTextSize ( " 4 " ) . x + circleRadius + 3.0 * dpiScale ;
pos1 . y - = ImGui : : CalcTextSize ( " 1 " ) . y * 0.5 ;
pos2 . y - = ImGui : : CalcTextSize ( " 2 " ) . y * 0.5 ;
pos3 . y - = ImGui : : CalcTextSize ( " 3 " ) . y * 0.5 ;
pos4 . y - = ImGui : : CalcTextSize ( " 4 " ) . y * 0.5 ;
2022-04-12 18:26:25 -05:00
dl - > AddText ( pos1 , colorC , " 1 " ) ;
dl - > AddText ( pos2 , colorM , " 2 " ) ;
dl - > AddText ( pos3 , colorC , " 3 " ) ;
dl - > AddText ( pos4 , colorC , " 4 " ) ;
2022-03-15 00:09:45 -05:00
break ;
}
}
break ;
2022-02-17 13:08:17 -05:00
default :
break ;
}
}
}
2023-10-16 16:57:04 -03:00
void FurnaceGUI : : drawESFMAlgorithm ( DivInstrumentESFM & esfm , const ImVec2 & size ) {
ImDrawList * dl = ImGui : : GetWindowDrawList ( ) ;
ImGuiWindow * window = ImGui : : GetCurrentWindow ( ) ;
ImVec2 minArea = window - > DC . CursorPos ;
ImVec2 maxArea = ImVec2 (
minArea . x + size . x ,
minArea . y + size . y
) ;
ImRect rect = ImRect ( minArea , maxArea ) ;
ImGuiStyle & style = ImGui : : GetStyle ( ) ;
ImU32 colorM = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_MOD ] ) ;
ImU32 colorC = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_CAR ] ) ;
ImU32 colorsL [ 8 ] ;
for ( int i = 0 ; i < 8 ; i + + ) {
float alpha = ( float ) i / 7.0f ;
ImVec4 color = uiColors [ GUI_COLOR_FM_ALG_LINE ] ;
color . w * = alpha ;
colorsL [ i ] = ImGui : : GetColorU32 ( color ) ;
}
ImGui : : ItemSize ( size , style . FramePadding . y ) ;
if ( ImGui : : ItemAdd ( rect , ImGui : : GetID ( " alg " ) ) ) {
ImGui : : RenderFrame ( rect . Min , rect . Max , ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_ALG_BG ] ) , true , style . FrameRounding ) ;
const float circleRadius = 6.0f * dpiScale + 1.0f ;
//int modFb = esfm.op[0].modIn&7;
int mod12 = esfm . op [ 1 ] . modIn & 7 ;
int mod23 = esfm . op [ 2 ] . modIn & 7 ;
int mod34 = esfm . op [ 3 ] . modIn & 7 ;
int out1 = esfm . op [ 0 ] . outLvl & 7 ;
int out2 = esfm . op [ 1 ] . outLvl & 7 ;
int out3 = esfm . op [ 2 ] . outLvl & 7 ;
int out4 = esfm . op [ 3 ] . outLvl & 7 ;
bool isMod [ 4 ] ;
for ( int i = 0 ; i < 4 ; i + + ) {
2023-10-22 11:46:34 -03:00
DivInstrumentESFM : : Operator & opE = esfm . op [ i ] ;
2023-10-16 16:57:04 -03:00
isMod [ i ] = true ;
if ( opE . outLvl = = 7 ) isMod [ i ] = false ;
else if ( opE . outLvl > 0 ) {
if ( i = = 3 ) isMod [ i ] = false ;
else {
DivInstrumentESFM : : Operator & opENext = esfm . op [ i + 1 ] ;
if ( opENext . modIn = = 0 ) isMod [ i ] = false ;
2023-10-22 11:46:34 -03:00
else if ( ( opE . outLvl - opENext . modIn ) > = 2 ) isMod [ i ] = false ;
2023-10-16 16:57:04 -03:00
}
}
}
ImVec2 posOp1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.2f , 0.25f ) ) ;
ImVec2 posOp2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.4f , 0.25f ) ) ;
ImVec2 posOp3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.6f , 0.25f ) ) ;
ImVec2 posOp4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.8f , 0.25f ) ) ;
ImVec2 posBusbarOp1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.2f , 0.75f ) ) ;
ImVec2 posBusbarOp2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.4f , 0.75f ) ) ;
ImVec2 posBusbarOp3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.6f , 0.75f ) ) ;
ImVec2 posBusbarOp4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.8f , 0.75f ) ) ;
ImVec2 posBusbarStart = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.15f , 0.75f ) ) ;
ImVec2 posBusbarEnd = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.85f , 0.75f ) ) ;
bool busbarStartSeen = false ;
for ( int i = 0 ; i < 4 ; i + + ) {
DivInstrumentESFM : : Operator & opE = esfm . op [ i ] ;
if ( opE . outLvl > 0 ) {
if ( ! busbarStartSeen ) {
busbarStartSeen = true ;
posBusbarStart = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.15f + 0.2f * i , 0.75f ) ) ;
}
posBusbarEnd = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.25f + 0.2f * i , 0.75f ) ) ;
}
}
if ( mod12 ) addAALine ( dl , posOp1 , posOp2 , colorsL [ mod12 ] ) ;
if ( mod23 ) addAALine ( dl , posOp2 , posOp3 , colorsL [ mod23 ] ) ;
if ( mod34 ) addAALine ( dl , posOp3 , posOp4 , colorsL [ mod34 ] ) ;
if ( out1 ) addAALine ( dl , posOp1 , posBusbarOp1 , colorsL [ out1 ] ) ;
if ( out2 ) addAALine ( dl , posOp2 , posBusbarOp2 , colorsL [ out2 ] ) ;
if ( out3 ) addAALine ( dl , posOp3 , posBusbarOp3 , colorsL [ out3 ] ) ;
if ( out4 ) addAALine ( dl , posOp4 , posBusbarOp4 , colorsL [ out4 ] ) ;
addAALine ( dl , posBusbarStart , posBusbarEnd , colorsL [ 2 ] ) ;
// addAALine(dl,posBusbarEnd,posBusbarEnd+ImVec2(-8.0f*dpiScale,-4.0f*dpiScale),colorsL[2]);
// addAALine(dl,posBusbarEnd,posBusbarEnd+ImVec2(-8.0f*dpiScale,4.0f*dpiScale),colorsL[2]);
// addAALine(dl,posBusbarStart+ImVec2(4.0f*dpiScale,-4.0f*dpiScale),posBusbarStart+ImVec2(4.0f*dpiScale,4.0f*dpiScale),colorsL[2]);
dl - > AddCircle ( posOp1 , 6.0f * dpiScale + 1.0f , isMod [ 0 ] ? colorM : colorC ) ;
dl - > AddCircleFilled ( posOp1 , 4.0f * dpiScale + 1.0f , isMod [ 0 ] ? colorM : colorC ) ;
dl - > AddCircleFilled ( posOp2 , 4.0f * dpiScale + 1.0f , isMod [ 1 ] ? colorM : colorC ) ;
dl - > AddCircleFilled ( posOp3 , 4.0f * dpiScale + 1.0f , isMod [ 2 ] ? colorM : colorC ) ;
dl - > AddCircleFilled ( posOp4 , 4.0f * dpiScale + 1.0f , isMod [ 3 ] ? colorM : colorC ) ;
posOp1 . x - = ImGui : : CalcTextSize ( " 1 " ) . x + circleRadius + 3.0f * dpiScale ;
posOp2 . x - = ImGui : : CalcTextSize ( " 2 " ) . x + circleRadius + 3.0f * dpiScale ;
posOp3 . x - = ImGui : : CalcTextSize ( " 3 " ) . x + circleRadius + 3.0f * dpiScale ;
posOp4 . x - = ImGui : : CalcTextSize ( " 4 " ) . x + circleRadius + 3.0f * dpiScale ;
posOp1 . y - = ImGui : : CalcTextSize ( " 1 " ) . y * 0.5f ;
posOp2 . y - = ImGui : : CalcTextSize ( " 2 " ) . y * 0.5f ;
posOp3 . y - = ImGui : : CalcTextSize ( " 3 " ) . y * 0.5f ;
posOp4 . y - = ImGui : : CalcTextSize ( " 4 " ) . y * 0.5f ;
dl - > AddText ( posOp1 , isMod [ 0 ] ? colorM : colorC , " 1 " ) ;
dl - > AddText ( posOp2 , isMod [ 1 ] ? colorM : colorC , " 2 " ) ;
dl - > AddText ( posOp3 , isMod [ 2 ] ? colorM : colorC , " 3 " ) ;
dl - > AddText ( posOp4 , isMod [ 3 ] ? colorM : colorC , " 4 " ) ;
}
}
2022-09-28 19:33:16 -05:00
void FurnaceGUI : : drawFMEnv ( unsigned char tl , unsigned char ar , unsigned char dr , unsigned char d2r , unsigned char rr , unsigned char sl , unsigned char sus , unsigned char egt , unsigned char algOrGlobalSus , float maxTl , float maxArDr , float maxRr , const ImVec2 & size , unsigned short instType ) {
2022-02-17 13:08:17 -05:00
ImDrawList * dl = ImGui : : GetWindowDrawList ( ) ;
ImGuiWindow * window = ImGui : : GetCurrentWindow ( ) ;
ImVec2 minArea = window - > DC . CursorPos ;
ImVec2 maxArea = ImVec2 (
minArea . x + size . x ,
minArea . y + size . y
) ;
ImRect rect = ImRect ( minArea , maxArea ) ;
ImGuiStyle & style = ImGui : : GetStyle ( ) ;
2022-04-12 18:26:25 -05:00
ImU32 color = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_ENVELOPE ] ) ;
ImU32 colorR = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_ENVELOPE_RELEASE ] ) ; // Relsease triangle
ImU32 colorS = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_ENVELOPE_SUS_GUIDE ] ) ; // Sustain horiz/vert line color
2022-02-17 13:08:17 -05:00
ImGui : : ItemSize ( size , style . FramePadding . y ) ;
2022-04-17 01:15:34 -05:00
if ( ImGui : : ItemAdd ( rect , ImGui : : GetID ( " fmEnv " ) ) ) {
2022-02-17 13:08:17 -05:00
ImGui : : RenderFrame ( rect . Min , rect . Max , ImGui : : GetColorU32 ( ImGuiCol_FrameBg ) , true , style . FrameRounding ) ;
2022-04-11 17:26:40 -04:00
//Adjust for OPLL global sustain setting
if ( instType = = DIV_INS_OPLL & & algOrGlobalSus = = 1.0 ) {
rr = 5.0 ;
}
2022-02-21 18:17:25 -05:00
//calculate x positions
2022-02-28 18:16:05 -05:00
float arPos = float ( maxArDr - ar ) / maxArDr ; //peak of AR, start of DR
float drPos = arPos + ( ( sl / 15.0 ) * ( float ( maxArDr - dr ) / maxArDr ) ) ; //end of DR, start of D2R
2022-02-22 09:16:36 -05:00
float d2rPos = drPos + ( ( ( 15.0 - sl ) / 15.0 ) * ( float ( 31.0 - d2r ) / 31.0 ) ) ; //End of D2R
2022-09-28 19:33:16 -05:00
float rrPos = ( float ( maxRr - rr ) / float ( maxRr ) ) ; //end of RR
2022-02-17 13:08:17 -05:00
2022-02-21 18:17:25 -05:00
//shrink all the x positions horizontally
2022-02-22 08:25:09 -05:00
arPos / = 2.0 ;
drPos / = 2.0 ;
d2rPos / = 2.0 ;
rrPos / = 1.0 ;
2022-02-21 17:23:07 -05:00
2022-02-21 18:17:25 -05:00
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.0 , 1.0 ) ) ; //the bottom corner
2022-02-28 18:16:05 -05:00
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( arPos , ( tl / maxTl ) ) ) ; //peak of AR, start of DR
ImVec2 pos3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( drPos , ( float ) ( ( tl / maxTl ) + ( sl / 15.0 ) - ( ( tl / maxTl ) * ( sl / 15.0 ) ) ) ) ) ; //end of DR, start of D2R
2022-02-21 18:17:25 -05:00
ImVec2 pos4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( d2rPos , 1.0 ) ) ; //end of D2R
2022-02-28 18:16:05 -05:00
ImVec2 posRStart = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.0 , ( tl / maxTl ) ) ) ; //release start
2022-02-21 23:17:19 -05:00
ImVec2 posREnd = ImLerp ( rect . Min , rect . Max , ImVec2 ( rrPos , 1.0 ) ) ; //release end
2022-02-28 18:16:05 -05:00
ImVec2 posSLineHEnd = ImLerp ( rect . Min , rect . Max , ImVec2 ( 1.0 , ( float ) ( ( tl / maxTl ) + ( sl / 15.0 ) - ( ( tl / maxTl ) * ( sl / 15.0 ) ) ) ) ) ; //sustain horizontal line end
2022-02-22 11:55:13 -05:00
ImVec2 posSLineVEnd = ImLerp ( rect . Min , rect . Max , ImVec2 ( drPos , 1.0 ) ) ; //sustain vertical line end
2022-04-10 14:01:55 +09:00
ImVec2 posDecayRate0Pt = ImLerp ( rect . Min , rect . Max , ImVec2 ( 1.0 , ( tl / maxTl ) ) ) ; //Height of the peak of AR, forever
ImVec2 posDecay2Rate0Pt = ImLerp ( rect . Min , rect . Max , ImVec2 ( 1.0 , ( float ) ( ( tl / maxTl ) + ( sl / 15.0 ) - ( ( tl / maxTl ) * ( sl / 15.0 ) ) ) ) ) ; //Height of the peak of SR, forever
2022-02-21 16:31:52 -05:00
2022-02-28 18:16:05 -05:00
//dl->Flags=ImDrawListFlags_AntiAliasedLines|ImDrawListFlags_AntiAliasedLinesUseTex;
2022-02-22 12:45:46 -05:00
if ( ar = = 0.0 ) { //if AR = 0, the envelope never starts
dl - > AddTriangleFilled ( posRStart , posREnd , pos1 , colorS ) ; //draw release as shaded triangle behind everything
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos1 , pos4 , color ) ; //draw line on ground
} else if ( dr = = 0.0 & & sl ! = 0.0 ) { //if DR = 0 and SL is not 0, then the envelope stays at max volume forever
2022-02-22 12:45:46 -05:00
dl - > AddTriangleFilled ( posRStart , posREnd , pos1 , colorS ) ; //draw release as shaded triangle behind everything
2022-02-28 18:16:05 -05:00
//addAALine(dl,pos3,posSLineHEnd,colorS); //draw horiz line through sustain level
//addAALine(dl,pos3,posSLineVEnd,colorS); //draw vert. line through sustain level
addAALine ( dl , pos1 , pos2 , color ) ; //A
addAALine ( dl , pos2 , posDecayRate0Pt , color ) ; //Line from A to end of graph
2024-01-17 10:37:23 -03:00
} else if ( d2r = = 0.0 | | ( ( instType = = DIV_INS_OPL | | instType = = DIV_INS_SNES | | instType = = DIV_INS_ESFM ) & & sus = = 1.0 ) | | ( instType = = DIV_INS_OPLL & & egt ! = 0.0 ) ) { //envelope stays at the sustain level forever
2022-02-22 12:45:46 -05:00
dl - > AddTriangleFilled ( posRStart , posREnd , pos1 , colorS ) ; //draw release as shaded triangle behind everything
2022-04-12 18:26:25 -05:00
addAALine ( dl , pos3 , posSLineHEnd , colorR ) ; //draw horiz line through sustain level
addAALine ( dl , pos3 , posSLineVEnd , colorR ) ; //draw vert. line through sustain level
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos1 , pos2 , color ) ; //A
addAALine ( dl , pos2 , pos3 , color ) ; //D
addAALine ( dl , pos3 , posDecay2Rate0Pt , color ) ; //Line from D to end of graph
} else { //draw graph normally
2022-02-22 12:45:46 -05:00
dl - > AddTriangleFilled ( posRStart , posREnd , pos1 , colorS ) ; //draw release as shaded triangle behind everything
2022-04-12 18:26:25 -05:00
addAALine ( dl , pos3 , posSLineHEnd , colorR ) ; //draw horiz line through sustain level
addAALine ( dl , pos3 , posSLineVEnd , colorR ) ; //draw vert. line through sustain level
2022-02-28 18:16:05 -05:00
addAALine ( dl , pos1 , pos2 , color ) ; //A
addAALine ( dl , pos2 , pos3 , color ) ; //D
addAALine ( dl , pos3 , pos4 , color ) ; //D2
2022-02-22 12:45:46 -05:00
}
2022-02-28 18:16:05 -05:00
//dl->Flags^=ImDrawListFlags_AntiAliasedLines|ImDrawListFlags_AntiAliasedLinesUseTex;
2022-02-17 13:08:17 -05:00
}
}
2024-07-31 19:22:01 +03:00
void FurnaceGUI : : drawSID3Env ( unsigned char tl , unsigned char ar , unsigned char dr , unsigned char d2r , unsigned char rr , unsigned char sl , unsigned char sus , unsigned char egt , unsigned char algOrGlobalSus , float maxTl , float maxArDr , float maxRr , const ImVec2 & size , unsigned short instType ) {
ImDrawList * dl = ImGui : : GetWindowDrawList ( ) ;
ImGuiWindow * window = ImGui : : GetCurrentWindow ( ) ;
ImVec2 minArea = window - > DC . CursorPos ;
ImVec2 maxArea = ImVec2 (
minArea . x + size . x ,
minArea . y + size . y
) ;
ImRect rect = ImRect ( minArea , maxArea ) ;
ImGuiStyle & style = ImGui : : GetStyle ( ) ;
ImU32 color = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_ENVELOPE ] ) ;
ImU32 colorR = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_ENVELOPE_RELEASE ] ) ; // Relsease triangle
ImU32 colorS = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_ENVELOPE_SUS_GUIDE ] ) ; // Sustain horiz/vert line color
ImGui : : ItemSize ( size , style . FramePadding . y ) ;
if ( ImGui : : ItemAdd ( rect , ImGui : : GetID ( " fmEnv " ) ) ) {
ImGui : : RenderFrame ( rect . Min , rect . Max , ImGui : : GetColorU32 ( ImGuiCol_FrameBg ) , true , style . FrameRounding ) ;
2024-09-21 17:37:30 -05:00
// Adjust for OPLL global sustain setting
if ( instType = = DIV_INS_OPLL & & algOrGlobalSus = = 1.0 ) {
rr = 5.0 ;
2024-07-31 19:22:01 +03:00
}
2024-09-21 17:37:30 -05:00
// calculate x positions
float arPos = float ( maxArDr - ( float ) ar ) / maxArDr ; // peak of AR, start of DR
float drPos = arPos + ( ( ( float ) sl / 255.0 ) * ( float ( maxArDr - ( float ) dr ) / maxArDr ) ) ; // end of DR, start of D2R
float d2rPos = drPos + ( ( ( 255.0 - ( float ) sl ) / 255.0 ) * ( float ( 255.0 - ( float ) d2r ) / 255.0 ) ) ; // End of D2R
float rrPos = ( float ( maxRr - ( float ) rr ) / float ( maxRr ) ) ; // end of RR
2024-07-31 19:22:01 +03:00
2024-09-21 17:37:30 -05:00
// shrink all the x positions horizontally
2024-07-31 19:22:01 +03:00
arPos / = 2.0 ;
drPos / = 2.0 ;
d2rPos / = 2.0 ;
rrPos / = 1.0 ;
2024-09-21 17:37:30 -05:00
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.0 , 1.0 ) ) ; // the bottom corner
ImVec2 pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( arPos , ( ( float ) tl / maxTl ) ) ) ; // peak of AR, start of DR
ImVec2 pos3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( drPos , ( float ) ( ( ( float ) tl / maxTl ) + ( ( float ) sl / 255.0 ) - ( ( ( float ) tl / maxTl ) * ( ( float ) sl / 255.0 ) ) ) ) ) ; // end of DR, start of D2R
ImVec2 pos4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( d2rPos , 1.0 ) ) ; // end of D2R
ImVec2 posRStart = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.0 , ( ( float ) tl / maxTl ) ) ) ; // release start
ImVec2 posREnd = ImLerp ( rect . Min , rect . Max , ImVec2 ( rrPos , 1.0 ) ) ; // release end
ImVec2 posSLineHEnd = ImLerp ( rect . Min , rect . Max , ImVec2 ( 1.0 , ( float ) ( ( ( float ) tl / maxTl ) + ( ( float ) sl / 255.0 ) - ( ( ( float ) tl / maxTl ) * ( ( float ) sl / 255.0 ) ) ) ) ) ; // sustain horizontal line end
ImVec2 posSLineVEnd = ImLerp ( rect . Min , rect . Max , ImVec2 ( drPos , 1.0 ) ) ; // sustain vertical line end
ImVec2 posDecayRate0Pt = ImLerp ( rect . Min , rect . Max , ImVec2 ( 1.0 , ( ( float ) tl / maxTl ) ) ) ; // Height of the peak of AR, forever
ImVec2 posDecay2Rate0Pt = ImLerp ( rect . Min , rect . Max , ImVec2 ( 1.0 , ( float ) ( ( ( float ) tl / maxTl ) + ( ( float ) sl / 255.0 ) - ( ( ( float ) tl / maxTl ) * ( ( float ) sl / 255.0 ) ) ) ) ) ; // Height of the peak of SR, forever
// dl->Flags=ImDrawListFlags_AntiAliasedLines|ImDrawListFlags_AntiAliasedLinesUseTex;
if ( ( float ) ar = = 0.0 ) { // if AR = 0, the envelope never starts
dl - > AddTriangleFilled ( posRStart , posREnd , pos1 , colorS ) ; // draw release as shaded triangle behind everything
addAALine ( dl , pos1 , pos4 , color ) ; // draw line on ground
} else if ( ( float ) dr = = 0.0 & & ( float ) sl ! = 0.0 ) { // if DR = 0 and SL is not 0, then the envelope stays at max volume forever
dl - > AddTriangleFilled ( posRStart , posREnd , pos1 , colorS ) ; // draw release as shaded triangle behind everything
// addAALine(dl,pos3,posSLineHEnd,colorS); // draw horiz line through sustain level
// addAALine(dl,pos3,posSLineVEnd,colorS); // draw vert. line through sustain level
addAALine ( dl , pos1 , pos2 , color ) ; // A
addAALine ( dl , pos2 , posDecayRate0Pt , color ) ; // Line from A to end of graph
} else if ( ( float ) d2r = = 0.0 | | ( ( instType = = DIV_INS_OPL | | instType = = DIV_INS_SNES | | instType = = DIV_INS_ESFM ) & & sus = = 1.0 ) | | ( instType = = DIV_INS_OPLL & & egt ! = 0.0 ) ) { // envelope stays at the sustain level forever
dl - > AddTriangleFilled ( posRStart , posREnd , pos1 , colorS ) ; // draw release as shaded triangle behind everything
addAALine ( dl , pos3 , posSLineHEnd , colorR ) ; // draw horiz line through sustain level
addAALine ( dl , pos3 , posSLineVEnd , colorR ) ; // draw vert. line through sustain level
addAALine ( dl , pos1 , pos2 , color ) ; // A
addAALine ( dl , pos2 , pos3 , color ) ; // D
addAALine ( dl , pos3 , posDecay2Rate0Pt , color ) ; // Line from D to end of graph
} else { // draw graph normally
dl - > AddTriangleFilled ( posRStart , posREnd , pos1 , colorS ) ; // draw release as shaded triangle behind everything
addAALine ( dl , pos3 , posSLineHEnd , colorR ) ; // draw horiz line through sustain level
addAALine ( dl , pos3 , posSLineVEnd , colorR ) ; // draw vert. line through sustain level
addAALine ( dl , pos1 , pos2 , color ) ; // A
addAALine ( dl , pos2 , pos3 , color ) ; // D
addAALine ( dl , pos3 , pos4 , color ) ; // D2
2024-07-31 19:22:01 +03:00
}
//dl->Flags^=ImDrawListFlags_AntiAliasedLines|ImDrawListFlags_AntiAliasedLinesUseTex;
}
}
2022-04-16 23:58:29 -05:00
void FurnaceGUI : : drawGBEnv ( unsigned char vol , unsigned char len , unsigned char sLen , bool dir , const ImVec2 & size ) {
2022-04-17 01:15:34 -05:00
ImDrawList * dl = ImGui : : GetWindowDrawList ( ) ;
2022-04-16 23:58:29 -05:00
ImGuiWindow * window = ImGui : : GetCurrentWindow ( ) ;
ImVec2 minArea = window - > DC . CursorPos ;
ImVec2 maxArea = ImVec2 (
minArea . x + size . x ,
minArea . y + size . y
) ;
ImRect rect = ImRect ( minArea , maxArea ) ;
ImGuiStyle & style = ImGui : : GetStyle ( ) ;
2022-04-17 01:15:34 -05:00
ImU32 color = ImGui : : GetColorU32 ( uiColors [ GUI_COLOR_FM_ENVELOPE ] ) ;
2022-04-16 23:58:29 -05:00
//ImU32 colorS=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_ENVELOPE_SUS_GUIDE]); // Sustain horiz/vert line color
ImGui : : ItemSize ( size , style . FramePadding . y ) ;
2022-04-17 01:15:34 -05:00
if ( ImGui : : ItemAdd ( rect , ImGui : : GetID ( " gbEnv " ) ) ) {
2022-04-16 23:58:29 -05:00
ImGui : : RenderFrame ( rect . Min , rect . Max , ImGui : : GetColorU32 ( ImGuiCol_FrameBg ) , true , style . FrameRounding ) ;
2022-04-17 01:15:34 -05:00
float volY = 1.0 - ( ( float ) vol / 15.0 ) ;
2025-10-12 14:21:33 -05:00
float lenPos = ( sLen > 63 ) ? 1.0 : ( ( float ) sLen / 384.0 ) ;
2022-04-17 01:15:34 -05:00
float envEndPoint = ( ( float ) len / 7.0 ) * ( ( float ) ( dir ? ( 15 - vol ) : vol ) / 15.0 ) ;
ImVec2 pos1 = ImLerp ( rect . Min , rect . Max , ImVec2 ( 0.0 , volY ) ) ;
ImVec2 pos2 ;
if ( dir ) {
if ( len > 0 ) {
if ( lenPos < envEndPoint ) {
pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( lenPos , volY * ( 1.0 - ( lenPos / envEndPoint ) ) ) ) ;
} else {
pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( envEndPoint , 0.0 ) ) ;
}
} else {
pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( lenPos , volY ) ) ;
}
} else {
if ( len > 0 ) {
if ( lenPos < envEndPoint ) {
pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( lenPos , volY + ( 1.0 - volY ) * ( lenPos / envEndPoint ) ) ) ;
} else {
pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( envEndPoint , 1.0 ) ) ;
}
} else {
pos2 = ImLerp ( rect . Min , rect . Max , ImVec2 ( lenPos , volY ) ) ;
}
}
2025-10-12 14:21:33 -05:00
ImVec2 pos3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( lenPos , ( len > 0 | | sLen < 64 ) ? ( ( dir & & sLen > 62 ) ? 0.0 : 1.0 ) : volY ) ) ;
2022-04-17 01:15:34 -05:00
addAALine ( dl , pos1 , pos2 , color ) ;
2025-10-12 14:21:33 -05:00
if ( lenPos > = envEndPoint & & sLen < 64 & & dir ) {
2022-04-17 01:15:34 -05:00
pos3 = ImLerp ( rect . Min , rect . Max , ImVec2 ( lenPos , 0.0 ) ) ;
addAALine ( dl , pos2 , pos3 , color ) ;
ImVec2 pos4 = ImLerp ( rect . Min , rect . Max , ImVec2 ( lenPos , 1.0 ) ) ;
addAALine ( dl , pos3 , pos4 , color ) ;
} else {
addAALine ( dl , pos2 , pos3 , color ) ;
}
2022-04-16 23:58:29 -05:00
}
}
2022-02-17 13:08:17 -05:00
# define P(x) if (x) { \
2022-03-21 16:17:51 -05:00
MARK_MODIFIED ; \
2022-02-17 13:08:17 -05:00
e - > notifyInsChange ( curIns ) ; \
2023-03-18 04:22:50 -05:00
updateFMPreview = true ; \
2022-02-17 13:08:17 -05:00
}
2023-03-18 04:22:50 -05:00
# define PARAMETER MARK_MODIFIED; e->notifyInsChange(curIns); updateFMPreview=true;
2022-02-17 13:08:17 -05:00
2022-05-07 18:30:16 -05:00
String genericGuide ( float value ) {
return fmt : : sprintf ( " %d " , ( int ) value ) ;
}
2022-02-17 13:08:17 -05:00
2022-08-22 19:09:08 -05:00
inline int deBit30 ( const int val ) {
if ( ( val & 0xc0000000 ) = = 0x40000000 | | ( val & 0xc0000000 ) = = 0x80000000 ) return val ^ 0x40000000 ;
return val ;
}
inline bool enBit30 ( const int val ) {
if ( ( val & 0xc0000000 ) = = 0x40000000 | | ( val & 0xc0000000 ) = = 0x80000000 ) return true ;
return false ;
}
2022-09-22 01:18:41 -05:00
2023-08-21 19:56:22 -05:00
void FurnaceGUI : : kvsConfig ( DivInstrument * ins , bool supportsKVS ) {
2023-08-20 20:18:27 -05:00
if ( fmPreviewOn ) {
2023-03-18 04:22:50 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " left click to restart \n middle click to pause \n right click to see algorithm " ) ) ;
2023-03-18 04:22:50 -05:00
}
if ( ImGui : : IsItemClicked ( ImGuiMouseButton_Left ) ) {
updateFMPreview = true ;
}
if ( ImGui : : IsItemClicked ( ImGuiMouseButton_Middle ) ) {
fmPreviewPaused = ! fmPreviewPaused ;
}
2023-08-21 19:56:22 -05:00
} else if ( supportsKVS ) {
2023-03-18 04:22:50 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " left click to configure TL scaling \n right click to see FM preview " ) ) ;
2023-03-18 04:22:50 -05:00
}
2023-08-21 19:56:22 -05:00
} else {
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " right click to see FM preview " ) ) ;
2023-08-21 19:56:22 -05:00
}
2022-09-22 01:18:41 -05:00
}
2023-08-20 20:18:27 -05:00
if ( ImGui : : IsItemClicked ( ImGuiMouseButton_Right ) ) {
2023-03-18 04:22:50 -05:00
fmPreviewOn = ! fmPreviewOn ;
}
2023-08-21 17:24:41 -05:00
if ( ImGui : : IsItemHovered ( ) & & CHECK_LONG_HOLD ) {
NOTIFY_LONG_HOLD ;
fmPreviewOn = ! fmPreviewOn ;
}
2023-08-21 19:56:22 -05:00
if ( ! fmPreviewOn & & supportsKVS ) {
2023-03-18 04:22:50 -05:00
int opCount = 4 ;
if ( ins - > type = = DIV_INS_OPLL ) opCount = 2 ;
if ( ins - > type = = DIV_INS_OPL ) opCount = ( ins - > fm . ops = = 4 ) ? 4 : 2 ;
if ( ImGui : : BeginPopupContextItem ( " IKVSOpt " , ImGuiPopupFlags_MouseButtonLeft ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " operator level changes with volume? " ) ) ;
2023-03-18 04:22:50 -05:00
if ( ImGui : : BeginTable ( " KVSTable " , 4 , ImGuiTableFlags_BordersInner ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch ) ;
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " c3 " , ImGuiTableColumnFlags_WidthStretch ) ;
for ( int i = 0 ; i < 4 ; i + + ) {
2024-01-20 14:09:51 -03:00
int o = ( opCount = = 4 & & ins - > type ! = DIV_INS_ESFM ) ? orderedOps [ i ] : i ;
2023-03-18 04:22:50 -05:00
if ( ! ( i & 1 ) ) ImGui : : TableNextRow ( ) ;
2024-05-26 19:31:17 -05:00
const char * label = _ ( " AUTO##OPKVS " ) ;
2023-03-18 04:22:50 -05:00
if ( ins - > fm . op [ o ] . kvs = = 0 ) {
2024-05-26 19:31:17 -05:00
label = _ ( " NO##OPKVS " ) ;
2023-03-18 04:22:50 -05:00
} else if ( ins - > fm . op [ o ] . kvs = = 1 ) {
2024-05-26 19:31:17 -05:00
label = _ ( " YES##OPKVS " ) ;
2023-03-18 04:22:50 -05:00
}
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %d " , i + 1 ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : PushID ( o ) ;
if ( ImGui : : Button ( label , ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , 0.0f ) ) ) {
if ( + + ins - > fm . op [ o ] . kvs > 2 ) ins - > fm . op [ o ] . kvs = 0 ;
PARAMETER ;
}
ImGui : : PopID ( ) ;
2022-09-22 01:18:41 -05:00
}
2023-03-18 04:22:50 -05:00
ImGui : : EndTable ( ) ;
2022-09-22 01:18:41 -05:00
}
2023-03-18 04:22:50 -05:00
ImGui : : EndPopup ( ) ;
2022-09-22 01:18:41 -05:00
}
}
}
2023-03-18 04:22:50 -05:00
void FurnaceGUI : : drawFMPreview ( const ImVec2 & size ) {
float asFloat [ FM_PREVIEW_SIZE ] ;
for ( int i = 0 ; i < FM_PREVIEW_SIZE ; i + + ) {
asFloat [ i ] = ( float ) fmPreview [ i ] / 8192.0f ;
}
ImGui : : PlotLines ( " ##DebugFMPreview " , asFloat , FM_PREVIEW_SIZE , 0 , NULL , - 1.0 , 1.0 , size ) ;
}
2025-03-10 12:35:05 -05:00
# define MACRO_VZOOM i.ins->temp.vZoom[i.macro->macroType]
# define MACRO_VSCROLL i.ins->temp.vScroll[i.macro->macroType]
2022-11-10 19:21:01 -05:00
void FurnaceGUI : : drawMacroEdit ( FurnaceGUIMacroDesc & i , int totalFit , float availableWidth , int index ) {
static float asFloat [ 256 ] ;
static int asInt [ 256 ] ;
static float loopIndicator [ 256 ] ;
static float bit30Indicator [ 256 ] ;
static bool doHighlight [ 256 ] ;
if ( ( i . macro - > open & 6 ) = = 0 ) {
for ( int j = 0 ; j < 256 ; j + + ) {
bit30Indicator [ j ] = 0 ;
if ( j + macroDragScroll > = i . macro - > len ) {
asFloat [ j ] = 0 ;
asInt [ j ] = 0 ;
} else {
asFloat [ j ] = deBit30 ( i . macro - > val [ j + macroDragScroll ] ) ;
2024-02-19 21:44:29 -05:00
asInt [ j ] = deBit30 ( i . macro - > val [ j + macroDragScroll ] ) ;
2022-11-10 19:21:01 -05:00
if ( i . bit30 ) bit30Indicator [ j ] = enBit30 ( i . macro - > val [ j + macroDragScroll ] ) ;
}
if ( j + macroDragScroll > = i . macro - > len | | ( j + macroDragScroll > i . macro - > rel & & i . macro - > loop < i . macro - > rel ) ) {
loopIndicator [ j ] = 0 ;
} else {
loopIndicator [ j ] = ( ( i . macro - > loop ! = 255 & & ( j + macroDragScroll ) > = i . macro - > loop ) ) | ( ( i . macro - > rel ! = 255 & & ( j + macroDragScroll ) = = i . macro - > rel ) < < 1 ) ;
}
2022-05-07 18:30:16 -05:00
}
2022-11-10 19:21:01 -05:00
ImGui : : PushStyleVar ( ImGuiStyleVar_FramePadding , ImVec2 ( 0.0f , 0.0f ) ) ;
2025-03-10 12:35:05 -05:00
if ( MACRO_VZOOM < 1 ) {
2024-01-01 14:59:00 -03:00
if ( i . macro - > macroType = = DIV_MACRO_ARP | | i . isArp ) {
2025-03-10 12:35:05 -05:00
MACRO_VZOOM = 24 ;
MACRO_VSCROLL = 120 - 12 ;
2025-10-04 18:39:07 -05:00
}
else if ( ( i . macro - > macroType = = DIV_MACRO_PITCH | | i . isPitch ) | | ( i . macro - > macroType = = DIV_MACRO_EX7 & & i . isPitch ) ) {
2025-03-10 12:35:05 -05:00
MACRO_VZOOM = 128 ;
MACRO_VSCROLL = 2048 - 64 ;
2022-11-10 19:21:01 -05:00
} else {
2025-03-10 12:35:05 -05:00
MACRO_VZOOM = i . max - i . min ;
MACRO_VSCROLL = 0 ;
2022-11-10 19:21:01 -05:00
}
2022-05-06 23:52:26 -05:00
}
2025-03-10 12:35:05 -05:00
if ( MACRO_VZOOM > ( i . max - i . min ) ) {
MACRO_VZOOM = i . max - i . min ;
2022-05-06 23:52:26 -05:00
}
2022-11-10 19:21:01 -05:00
memset ( doHighlight , 0 , 256 * sizeof ( bool ) ) ;
if ( e - > isRunning ( ) ) for ( int j = 0 ; j < e - > getTotalChannelCount ( ) ; j + + ) {
DivChannelState * chanState = e - > getChanState ( j ) ;
if ( chanState = = NULL ) continue ;
2022-05-06 23:52:26 -05:00
2022-11-10 19:21:01 -05:00
if ( chanState - > keyOff ) continue ;
if ( chanState - > lastIns ! = curIns ) continue ;
DivMacroInt * macroInt = e - > getMacroInt ( j ) ;
if ( macroInt = = NULL ) continue ;
2023-10-05 23:51:34 -05:00
DivMacroStruct * macroStruct = macroInt - > structByType ( i . macro - > macroType ) ;
2022-11-10 19:21:01 -05:00
if ( macroStruct = = NULL ) continue ;
if ( macroStruct - > lastPos > i . macro - > len ) continue ;
if ( macroStruct - > lastPos < macroDragScroll ) continue ;
if ( macroStruct - > lastPos > 255 ) continue ;
if ( ! macroStruct - > actualHad ) continue ;
2022-10-07 16:47:18 -05:00
2022-11-10 19:21:01 -05:00
doHighlight [ macroStruct - > lastPos - macroDragScroll ] = true ;
2022-05-07 18:30:16 -05:00
}
2022-11-10 19:21:01 -05:00
if ( i . isBitfield ) {
2024-08-22 18:11:15 +03:00
PlotBitfield ( " ##IMacro " , asInt , totalFit , 0 , i . bitfieldBits , i . max , ImVec2 ( availableWidth , ( i . macro - > open & 1 ) ? ( i . height * dpiScale ) : ( 32.0f * dpiScale ) ) , sizeof ( float ) , doHighlight , uiColors [ GUI_COLOR_MACRO_HIGHLIGHT ] , i . color , i . hoverFunc , i . hoverFuncUser ) ;
2022-11-10 19:21:01 -05:00
} else {
2025-03-10 12:35:05 -05:00
PlotCustom ( " ##IMacro " , asFloat , totalFit , macroDragScroll , NULL , i . min + MACRO_VSCROLL , i . min + MACRO_VSCROLL + MACRO_VZOOM , ImVec2 ( availableWidth , ( i . macro - > open & 1 ) ? ( i . height * dpiScale ) : ( 32.0f * dpiScale ) ) , sizeof ( float ) , i . color , i . macro - > len - macroDragScroll , i . hoverFunc , i . hoverFuncUser , i . blockMode , ( i . macro - > open & 1 ) ? genericGuide : NULL , doHighlight , uiColors [ GUI_COLOR_MACRO_HIGHLIGHT ] ) ;
2022-05-06 23:52:26 -05:00
}
2022-11-10 19:21:01 -05:00
if ( ( i . macro - > open & 1 ) & & ( ImGui : : IsItemClicked ( ImGuiMouseButton_Left ) | | ImGui : : IsItemClicked ( ImGuiMouseButton_Right ) ) ) {
2022-12-01 04:28:12 -05:00
ImGui : : InhibitInertialScroll ( ) ;
2022-11-10 19:21:01 -05:00
macroDragStart = ImGui : : GetItemRectMin ( ) ;
macroDragAreaSize = ImVec2 ( availableWidth , i . height * dpiScale ) ;
if ( i . isBitfield ) {
macroDragMin = i . min ;
macroDragMax = i . max ;
} else {
2025-03-10 12:35:05 -05:00
macroDragMin = i . min + MACRO_VSCROLL ;
macroDragMax = i . min + MACRO_VSCROLL + MACRO_VZOOM ;
2022-11-10 19:21:01 -05:00
}
macroDragBitMode = i . isBitfield ;
macroDragInitialValueSet = false ;
macroDragInitialValue = false ;
macroDragLen = totalFit ;
macroDragActive = true ;
macroDragBit30 = i . bit30 ;
macroDragSettingBit30 = false ;
macroDragTarget = i . macro - > val ;
macroDragChar = false ;
macroDragLineMode = ( i . isBitfield ) ? false : ImGui : : IsItemClicked ( ImGuiMouseButton_Right ) ;
macroDragLineInitial = ImVec2 ( 0 , 0 ) ;
lastMacroDesc = i ;
processDrags ( ImGui : : GetMousePos ( ) . x , ImGui : : GetMousePos ( ) . y ) ;
2022-05-06 23:52:26 -05:00
}
2022-11-10 19:21:01 -05:00
if ( ( i . macro - > open & 1 ) ) {
if ( ImGui : : IsItemHovered ( ) ) {
if ( ctrlWheeling ) {
if ( ImGui : : IsKeyDown ( ImGuiKey_LeftShift ) | | ImGui : : IsKeyDown ( ImGuiKey_RightShift ) ) {
2025-03-10 12:35:05 -05:00
MACRO_VZOOM + = wheelY * ( 1 + ( MACRO_VZOOM > > 4 ) ) ;
if ( MACRO_VZOOM < 1 ) MACRO_VZOOM = 1 ;
if ( MACRO_VZOOM > ( i . max - i . min ) ) MACRO_VZOOM = i . max - i . min ;
if ( ( MACRO_VSCROLL + MACRO_VZOOM ) > ( i . max - i . min ) ) {
MACRO_VSCROLL = ( i . max - i . min ) - MACRO_VZOOM ;
2022-10-07 16:47:18 -05:00
}
2024-09-11 11:52:42 -07:00
} else if ( settings . autoMacroStepSize = = 0 ) {
2022-11-10 19:21:01 -05:00
macroPointSize + = wheelY ;
if ( macroPointSize < 1 ) macroPointSize = 1 ;
if ( macroPointSize > 256 ) macroPointSize = 256 ;
2022-10-07 16:47:18 -05:00
}
2022-11-10 19:21:01 -05:00
} else if ( ( ImGui : : IsKeyDown ( ImGuiKey_LeftShift ) | | ImGui : : IsKeyDown ( ImGuiKey_RightShift ) ) & & wheelY ! = 0 ) {
2025-03-10 12:35:05 -05:00
MACRO_VSCROLL + = wheelY * ( 1 + ( MACRO_VZOOM > > 4 ) ) ;
if ( MACRO_VSCROLL < 0 ) MACRO_VSCROLL = 0 ;
if ( MACRO_VSCROLL > ( ( i . max - i . min ) - MACRO_VZOOM ) ) MACRO_VSCROLL = ( i . max - i . min ) - MACRO_VZOOM ;
2022-05-06 23:52:26 -05:00
}
}
2022-02-17 13:08:17 -05:00
2022-11-10 19:21:01 -05:00
// slider
if ( ! i . isBitfield ) {
if ( settings . oldMacroVSlider ) {
ImGui : : SameLine ( 0.0f ) ;
2025-03-10 12:35:05 -05:00
if ( ImGui : : VSliderInt ( " ##IMacroVScroll " , ImVec2 ( 20.0f * dpiScale , i . height * dpiScale ) , & MACRO_VSCROLL , 0 , ( i . max - i . min ) - MACRO_VZOOM , " " , ImGuiSliderFlags_NoInput ) ) {
if ( MACRO_VSCROLL < 0 ) MACRO_VSCROLL = 0 ;
if ( MACRO_VSCROLL > ( ( i . max - i . min ) - MACRO_VZOOM ) ) MACRO_VSCROLL = ( i . max - i . min ) - MACRO_VZOOM ;
2022-10-07 04:11:45 -05:00
}
2022-11-10 19:21:01 -05:00
if ( ImGui : : IsItemHovered ( ) & & ctrlWheeling ) {
2025-03-10 12:35:05 -05:00
MACRO_VSCROLL + = wheelY * ( 1 + ( MACRO_VZOOM > > 4 ) ) ;
if ( MACRO_VSCROLL < 0 ) MACRO_VSCROLL = 0 ;
if ( MACRO_VSCROLL > ( ( i . max - i . min ) - MACRO_VZOOM ) ) MACRO_VSCROLL = ( i . max - i . min ) - MACRO_VZOOM ;
2022-10-07 04:11:45 -05:00
}
2022-11-10 19:21:01 -05:00
} else {
2025-03-10 12:35:05 -05:00
ImS64 scrollV = ( i . max - i . min - MACRO_VZOOM ) - MACRO_VSCROLL ;
ImS64 availV = MACRO_VZOOM ;
2022-11-10 19:21:01 -05:00
ImS64 contentsV = ( i . max - i . min ) ;
ImGui : : SameLine ( 0.0f ) ;
ImGui : : SetCursorPosX ( ImGui : : GetCursorPosX ( ) - ImGui : : GetStyle ( ) . ItemSpacing . x ) ;
ImRect scrollbarPos = ImRect ( ImGui : : GetCursorScreenPos ( ) , ImGui : : GetCursorScreenPos ( ) ) ;
scrollbarPos . Max . x + = ImGui : : GetStyle ( ) . ScrollbarSize ;
scrollbarPos . Max . y + = i . height * dpiScale ;
ImGui : : Dummy ( ImVec2 ( ImGui : : GetStyle ( ) . ScrollbarSize , i . height * dpiScale ) ) ;
if ( ImGui : : IsItemHovered ( ) & & ctrlWheeling ) {
2025-03-10 12:35:05 -05:00
MACRO_VSCROLL + = wheelY * ( 1 + ( MACRO_VZOOM > > 4 ) ) ;
if ( MACRO_VSCROLL < 0 ) MACRO_VSCROLL = 0 ;
if ( MACRO_VSCROLL > ( ( i . max - i . min ) - MACRO_VZOOM ) ) MACRO_VSCROLL = ( i . max - i . min ) - MACRO_VZOOM ;
2022-10-07 04:11:45 -05:00
}
2022-08-20 01:10:30 -05:00
2023-08-16 00:43:15 -05:00
ImGuiID scrollbarID = ImGui : : GetID ( " ##IMacroVScroll " ) ;
2022-11-10 19:21:01 -05:00
ImGui : : KeepAliveID ( scrollbarID ) ;
if ( ImGui : : ScrollbarEx ( scrollbarPos , scrollbarID , ImGuiAxis_Y , & scrollV , availV , contentsV , 0 ) ) {
2025-03-10 12:35:05 -05:00
MACRO_VSCROLL = ( i . max - i . min - MACRO_VZOOM ) - scrollV ;
2022-10-07 04:11:45 -05:00
}
2022-05-06 23:52:26 -05:00
}
2022-11-10 19:21:01 -05:00
}
2022-10-07 16:47:18 -05:00
2022-11-10 19:21:01 -05:00
// bit 30 area
if ( i . bit30 ) {
PlotCustom ( " ##IMacroBit30 " , bit30Indicator , totalFit , macroDragScroll , NULL , 0 , 1 , ImVec2 ( availableWidth , 12.0f * dpiScale ) , sizeof ( float ) , i . color , i . macro - > len - macroDragScroll , & macroHoverBit30 ) ;
if ( ImGui : : IsItemClicked ( ImGuiMouseButton_Left ) ) {
2022-12-01 04:28:12 -05:00
ImGui : : InhibitInertialScroll ( ) ;
2022-10-07 04:11:45 -05:00
macroDragStart = ImGui : : GetItemRectMin ( ) ;
2022-11-10 19:21:01 -05:00
macroDragAreaSize = ImVec2 ( availableWidth , 12.0f * dpiScale ) ;
2022-10-07 04:11:45 -05:00
macroDragInitialValueSet = false ;
macroDragInitialValue = false ;
macroDragLen = totalFit ;
macroDragActive = true ;
macroDragBit30 = i . bit30 ;
2022-11-10 19:21:01 -05:00
macroDragSettingBit30 = true ;
2022-10-07 04:11:45 -05:00
macroDragTarget = i . macro - > val ;
macroDragChar = false ;
2022-11-10 19:21:01 -05:00
macroDragLineMode = false ;
2022-10-07 04:11:45 -05:00
macroDragLineInitial = ImVec2 ( 0 , 0 ) ;
lastMacroDesc = i ;
processDrags ( ImGui : : GetMousePos ( ) . x , ImGui : : GetMousePos ( ) . y ) ;
2022-08-22 03:52:32 -05:00
}
2022-11-10 19:21:01 -05:00
}
2022-10-07 04:11:45 -05:00
2022-11-10 19:21:01 -05:00
// loop area
PlotCustom ( " ##IMacroLoop " , loopIndicator , totalFit , macroDragScroll , NULL , 0 , 2 , ImVec2 ( availableWidth , 12.0f * dpiScale ) , sizeof ( float ) , i . color , i . macro - > len - macroDragScroll , & macroHoverLoop ) ;
if ( ImGui : : IsItemClicked ( ImGuiMouseButton_Left ) ) {
2022-12-01 04:28:12 -05:00
ImGui : : InhibitInertialScroll ( ) ;
2022-11-10 19:21:01 -05:00
macroLoopDragStart = ImGui : : GetItemRectMin ( ) ;
macroLoopDragAreaSize = ImVec2 ( availableWidth , 12.0f * dpiScale ) ;
macroLoopDragLen = totalFit ;
if ( ImGui : : IsKeyDown ( ImGuiKey_LeftShift ) | | ImGui : : IsKeyDown ( ImGuiKey_RightShift ) ) {
macroLoopDragTarget = & i . macro - > rel ;
} else {
macroLoopDragTarget = & i . macro - > loop ;
2022-08-22 03:52:32 -05:00
}
2022-11-10 19:21:01 -05:00
macroLoopDragActive = true ;
processDrags ( ImGui : : GetMousePos ( ) . x , ImGui : : GetMousePos ( ) . y ) ;
}
if ( ImGui : : IsItemClicked ( ImGuiMouseButton_Right ) ) {
2022-12-01 04:28:12 -05:00
ImGui : : InhibitInertialScroll ( ) ;
2022-11-10 19:21:01 -05:00
if ( ImGui : : IsKeyDown ( ImGuiKey_LeftShift ) | | ImGui : : IsKeyDown ( ImGuiKey_RightShift ) ) {
i . macro - > rel = 255 ;
} else {
i . macro - > loop = 255 ;
2022-08-22 03:52:32 -05:00
}
2022-11-10 19:21:01 -05:00
}
ImGui : : SetNextItemWidth ( availableWidth ) ;
String & mmlStr = mmlString [ index ] ;
if ( ImGui : : InputText ( " ##IMacroMML " , & mmlStr ) ) {
2024-08-17 13:40:15 +03:00
decodeMMLStr ( mmlStr , i . macro - > val , i . macro - > len , i . macro - > loop , i . min , ( i . isBitfield ) ? ( ( 1 < < ( i . isBitfield ? ( i . max ) : 0 ) ) - 1 ) : i . max , i . macro - > rel , i . bit30 ) ;
2022-11-10 19:21:01 -05:00
}
if ( ! ImGui : : IsItemActive ( ) ) {
encodeMMLStr ( mmlStr , i . macro - > val , i . macro - > len , i . macro - > loop , i . macro - > rel , false , i . bit30 ) ;
}
}
ImGui : : PopStyleVar ( ) ;
} else {
if ( i . macro - > open & 2 ) {
2025-05-23 18:29:02 -05:00
const bool compact = ( availableWidth < 300.0f * dpiScale ) ;
if ( ImGui : : BeginTable ( " MacroADSR " , compact ? 2 : 4 ) ) {
2022-11-10 19:21:01 -05:00
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch , 0.3 ) ;
2025-05-23 18:29:02 -05:00
if ( ! compact ) {
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " c3 " , ImGuiTableColumnFlags_WidthStretch , 0.3 ) ;
}
2022-11-10 19:21:01 -05:00
//ImGui::TableSetupColumn("c4",ImGuiTableColumnFlags_WidthStretch,0.4);
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2023-08-20 14:39:03 -07:00
ImGui : : AlignTextToFramePadding ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Bottom " ) ) ;
2022-11-10 19:21:01 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( ImGui : : InputInt ( " ##MABottom " , & i . macro - > val [ 0 ] , 1 , 16 ) ) { PARAMETER
if ( i . macro - > val [ 0 ] < i . min ) i . macro - > val [ 0 ] = i . min ;
if ( i . macro - > val [ 0 ] > i . max ) i . macro - > val [ 0 ] = i . max ;
2022-08-22 03:52:32 -05:00
}
2022-10-07 04:11:45 -05:00
2025-05-23 18:29:02 -05:00
if ( compact ) ImGui : : TableNextRow ( ) ;
2022-11-10 19:21:01 -05:00
ImGui : : TableNextColumn ( ) ;
2025-05-23 18:29:02 -05:00
ImGui : : AlignTextToFramePadding ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Top " ) ) ;
2022-11-10 19:21:01 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( ImGui : : InputInt ( " ##MATop " , & i . macro - > val [ 1 ] , 1 , 16 ) ) { PARAMETER
if ( i . macro - > val [ 1 ] < i . min ) i . macro - > val [ 1 ] = i . min ;
if ( i . macro - > val [ 1 ] > i . max ) i . macro - > val [ 1 ] = i . max ;
2022-05-06 23:52:26 -05:00
}
2022-05-07 16:25:02 -05:00
2022-11-10 19:21:01 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2023-08-20 14:39:03 -07:00
ImGui : : AlignTextToFramePadding ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Attack " ) ) ;
2022-11-10 19:21:01 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##MAAR " , & i . macro - > val [ 2 ] , 0 , 255 ) ) { PARAMETER
if ( i . macro - > val [ 2 ] < 0 ) i . macro - > val [ 2 ] = 0 ;
if ( i . macro - > val [ 2 ] > 255 ) i . macro - > val [ 2 ] = 255 ;
2023-04-20 03:43:35 -05:00
} rightClickable
2022-02-17 13:08:17 -05:00
2025-05-23 18:29:02 -05:00
if ( compact ) {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " Hold " ) ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##MAHT " , & i . macro - > val [ 3 ] , 0 , 255 ) ) { PARAMETER
if ( i . macro - > val [ 3 ] < 0 ) i . macro - > val [ 3 ] = 0 ;
if ( i . macro - > val [ 3 ] > 255 ) i . macro - > val [ 3 ] = 255 ;
} rightClickable
2022-10-07 04:11:45 -05:00
2025-05-23 18:29:02 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " Decay " ) ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##MADR " , & i . macro - > val [ 4 ] , 0 , 255 ) ) { PARAMETER
if ( i . macro - > val [ 4 ] < 0 ) i . macro - > val [ 4 ] = 0 ;
if ( i . macro - > val [ 4 ] > 255 ) i . macro - > val [ 4 ] = 255 ;
} rightClickable
2022-10-07 04:11:45 -05:00
2025-05-23 18:29:02 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " Sustain " ) ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##MASL " , & i . macro - > val [ 5 ] , 0 , 255 ) ) { PARAMETER
if ( i . macro - > val [ 5 ] < 0 ) i . macro - > val [ 5 ] = 0 ;
if ( i . macro - > val [ 5 ] > 255 ) i . macro - > val [ 5 ] = 255 ;
} rightClickable
2022-08-20 01:10:30 -05:00
2025-05-23 18:29:02 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " SusTime " ) ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##MAST " , & i . macro - > val [ 6 ] , 0 , 255 ) ) { PARAMETER
if ( i . macro - > val [ 6 ] < 0 ) i . macro - > val [ 6 ] = 0 ;
if ( i . macro - > val [ 6 ] > 255 ) i . macro - > val [ 6 ] = 255 ;
} rightClickable
2022-08-20 01:10:30 -05:00
2025-05-23 18:29:02 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " SusDecay " ) ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##MASR " , & i . macro - > val [ 7 ] , 0 , 255 ) ) { PARAMETER
if ( i . macro - > val [ 7 ] < 0 ) i . macro - > val [ 7 ] = 0 ;
if ( i . macro - > val [ 7 ] > 255 ) i . macro - > val [ 7 ] = 255 ;
} rightClickable
2022-08-20 01:10:30 -05:00
2025-05-23 18:29:02 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " Release " ) ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##MARR " , & i . macro - > val [ 8 ] , 0 , 255 ) ) { PARAMETER
if ( i . macro - > val [ 8 ] < 0 ) i . macro - > val [ 8 ] = 0 ;
if ( i . macro - > val [ 8 ] > 255 ) i . macro - > val [ 8 ] = 255 ;
} rightClickable
} else {
ImGui : : TableNextColumn ( ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " Sustain " ) ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##MASL " , & i . macro - > val [ 5 ] , 0 , 255 ) ) { PARAMETER
if ( i . macro - > val [ 5 ] < 0 ) i . macro - > val [ 5 ] = 0 ;
if ( i . macro - > val [ 5 ] > 255 ) i . macro - > val [ 5 ] = 255 ;
} rightClickable
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " Hold " ) ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##MAHT " , & i . macro - > val [ 3 ] , 0 , 255 ) ) { PARAMETER
if ( i . macro - > val [ 3 ] < 0 ) i . macro - > val [ 3 ] = 0 ;
if ( i . macro - > val [ 3 ] > 255 ) i . macro - > val [ 3 ] = 255 ;
} rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " SusTime " ) ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##MAST " , & i . macro - > val [ 6 ] , 0 , 255 ) ) { PARAMETER
if ( i . macro - > val [ 6 ] < 0 ) i . macro - > val [ 6 ] = 0 ;
if ( i . macro - > val [ 6 ] > 255 ) i . macro - > val [ 6 ] = 255 ;
} rightClickable
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " Decay " ) ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##MADR " , & i . macro - > val [ 4 ] , 0 , 255 ) ) { PARAMETER
if ( i . macro - > val [ 4 ] < 0 ) i . macro - > val [ 4 ] = 0 ;
if ( i . macro - > val [ 4 ] > 255 ) i . macro - > val [ 4 ] = 255 ;
} rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " SusDecay " ) ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##MASR " , & i . macro - > val [ 7 ] , 0 , 255 ) ) { PARAMETER
if ( i . macro - > val [ 7 ] < 0 ) i . macro - > val [ 7 ] = 0 ;
if ( i . macro - > val [ 7 ] > 255 ) i . macro - > val [ 7 ] = 255 ;
} rightClickable
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " Release " ) ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##MARR " , & i . macro - > val [ 8 ] , 0 , 255 ) ) { PARAMETER
if ( i . macro - > val [ 8 ] < 0 ) i . macro - > val [ 8 ] = 0 ;
if ( i . macro - > val [ 8 ] > 255 ) i . macro - > val [ 8 ] = 255 ;
} rightClickable
}
2022-08-20 01:10:30 -05:00
2022-11-10 19:21:01 -05:00
ImGui : : EndTable ( ) ;
}
}
if ( i . macro - > open & 4 ) {
2025-05-23 18:29:02 -05:00
const bool compact = ( availableWidth < 300.0f * dpiScale ) ;
if ( ImGui : : BeginTable ( " MacroLFO " , compact ? 2 : 4 ) ) {
2022-11-10 19:21:01 -05:00
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch , 0.3 ) ;
2025-05-23 18:29:02 -05:00
if ( ! compact ) {
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " c3 " , ImGuiTableColumnFlags_WidthStretch , 0.3 ) ;
}
2022-08-20 01:10:30 -05:00
2022-11-10 19:21:01 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2023-08-20 14:39:03 -07:00
ImGui : : AlignTextToFramePadding ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Bottom " ) ) ;
2022-11-10 19:21:01 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( ImGui : : InputInt ( " ##MABottom " , & i . macro - > val [ 0 ] , 1 , 16 ) ) { PARAMETER
if ( i . macro - > val [ 0 ] < i . min ) i . macro - > val [ 0 ] = i . min ;
if ( i . macro - > val [ 0 ] > i . max ) i . macro - > val [ 0 ] = i . max ;
}
2022-08-20 01:10:30 -05:00
2025-05-23 18:29:02 -05:00
if ( compact ) ImGui : : TableNextRow ( ) ;
2022-11-10 19:21:01 -05:00
ImGui : : TableNextColumn ( ) ;
2025-05-23 18:29:02 -05:00
ImGui : : AlignTextToFramePadding ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Top " ) ) ;
2022-11-10 19:21:01 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( ImGui : : InputInt ( " ##MATop " , & i . macro - > val [ 1 ] , 1 , 16 ) ) { PARAMETER
if ( i . macro - > val [ 1 ] < i . min ) i . macro - > val [ 1 ] = i . min ;
if ( i . macro - > val [ 1 ] > i . max ) i . macro - > val [ 1 ] = i . max ;
2022-10-07 04:11:45 -05:00
}
2022-08-20 01:10:30 -05:00
2022-11-10 19:21:01 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2023-08-20 14:39:03 -07:00
ImGui : : AlignTextToFramePadding ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Speed " ) ) ;
2022-11-10 19:21:01 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##MLSpeed " , & i . macro - > val [ 11 ] , 0 , 255 ) ) { PARAMETER
if ( i . macro - > val [ 11 ] < 0 ) i . macro - > val [ 11 ] = 0 ;
if ( i . macro - > val [ 11 ] > 255 ) i . macro - > val [ 11 ] = 255 ;
2023-04-20 03:43:35 -05:00
} rightClickable
2022-10-07 15:06:04 -05:00
2025-05-23 18:29:02 -05:00
if ( compact ) ImGui : : TableNextRow ( ) ;
2022-11-10 19:21:01 -05:00
ImGui : : TableNextColumn ( ) ;
2025-05-23 18:29:02 -05:00
ImGui : : AlignTextToFramePadding ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Phase " ) ) ;
2022-11-10 19:21:01 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##MLPhase " , & i . macro - > val [ 13 ] , 0 , 1023 ) ) { PARAMETER
if ( i . macro - > val [ 13 ] < 0 ) i . macro - > val [ 13 ] = 0 ;
if ( i . macro - > val [ 13 ] > 1023 ) i . macro - > val [ 13 ] = 1023 ;
2023-04-20 03:43:35 -05:00
} rightClickable
2022-10-07 04:11:45 -05:00
2025-05-23 18:29:02 -05:00
ImGui : : TableNextRow ( ) ;
2022-11-10 19:21:01 -05:00
ImGui : : TableNextColumn ( ) ;
2023-08-20 14:39:03 -07:00
ImGui : : AlignTextToFramePadding ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Shape " ) ) ;
2022-11-10 19:21:01 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##MLShape " , & i . macro - > val [ 12 ] , 0 , 2 , macroLFOShapes [ i . macro - > val [ 12 ] & 3 ] ) ) { PARAMETER
if ( i . macro - > val [ 12 ] < 0 ) i . macro - > val [ 12 ] = 0 ;
if ( i . macro - > val [ 12 ] > 2 ) i . macro - > val [ 12 ] = 2 ;
2023-04-20 03:43:35 -05:00
} rightClickable
2022-10-07 04:11:45 -05:00
2022-11-10 19:21:01 -05:00
ImGui : : EndTable ( ) ;
}
}
}
}
2022-05-07 16:25:02 -05:00
2022-11-10 19:21:01 -05:00
# define BUTTON_TO_SET_MODE(buttonType) \
if ( buttonType ( macroTypeLabels [ ( i . macro - > open > > 1 ) & 3 ] ) ) { \
unsigned char prevOpen = i . macro - > open ; \
2023-10-11 03:36:21 -05:00
if ( i . macro - > open > = 4 ) { \
i . macro - > open & = ( ~ 6 ) ; \
} else { \
i . macro - > open + = 2 ; \
2022-11-10 19:21:01 -05:00
} \
\
/* check whether macro type is now ADSR/LFO or sequence */ \
if ( ( ( prevOpen & 6 ) ? 1 : 0 ) ! = ( ( i . macro - > open & 6 ) ? 1 : 0 ) ) { \
/* swap memory */ \
/* this way the macro isn't corrupted if the user decides to go */ \
/* back to sequence mode */ \
2025-03-10 12:35:05 -05:00
i . macro - > len ^ = i . ins - > temp . lenMemory [ i . macro - > macroType ] ; \
i . ins - > temp . lenMemory [ i . macro - > macroType ] ^ = i . macro - > len ; \
i . macro - > len ^ = i . ins - > temp . lenMemory [ i . macro - > macroType ] ; \
2022-11-10 19:21:01 -05:00
\
for ( int j = 0 ; j < 16 ; j + + ) { \
2025-03-10 12:35:05 -05:00
i . macro - > val [ j ] ^ = i . ins - > temp . typeMemory [ i . macro - > macroType ] [ j ] ; \
i . ins - > temp . typeMemory [ i . macro - > macroType ] [ j ] ^ = i . macro - > val [ j ] ; \
i . macro - > val [ j ] ^ = i . ins - > temp . typeMemory [ i . macro - > macroType ] [ j ] ; \
2022-11-10 19:21:01 -05:00
} \
\
/* if ADSR/LFO, populate min/max */ \
if ( i . macro - > open & 6 ) { \
2023-08-24 04:31:32 -05:00
if ( i . macro - > val [ 0 ] = = 0 & & i . macro - > val [ 1 ] = = 0 ) { \
2023-08-22 14:23:32 -07:00
i . macro - > val [ 0 ] = i . min ; \
i . macro - > val [ 1 ] = i . max ; \
} \
2023-08-24 04:31:32 -05:00
i . macro - > val [ 0 ] = CLAMP ( i . macro - > val [ 0 ] , i . min , i . max ) ; \
i . macro - > val [ 1 ] = CLAMP ( i . macro - > val [ 1 ] , i . min , i . max ) ; \
2022-11-10 19:21:01 -05:00
} \
} \
PARAMETER ; \
} \
if ( ImGui : : IsItemHovered ( ) ) { \
switch ( i . macro - > open & 6 ) { \
case 0 : \
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Macro type: Sequence " ) ) ; \
2022-11-10 19:21:01 -05:00
break ; \
case 2 : \
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Macro type: ADSR " ) ) ; \
2022-11-10 19:21:01 -05:00
break ; \
case 4 : \
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Macro type: LFO " ) ) ; \
2022-11-10 19:21:01 -05:00
break ; \
default : \
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Macro type: What's going on here? " ) ) ; \
2022-11-10 19:21:01 -05:00
break ; \
} \
} \
if ( i . macro - > open & 6 ) { \
i . macro - > len = 16 ; \
}
2022-05-07 16:25:02 -05:00
2022-11-11 00:46:39 -05:00
# define BUTTON_TO_SET_PROPS(_x) \
2023-08-30 14:06:04 -05:00
pushToggleColors ( _x . macro - > speed ! = 1 | | _x . macro - > delay ) ; \
2022-11-10 19:21:01 -05:00
ImGui : : Button ( ICON_FA_ELLIPSIS_H " ##IMacroSet " ) ; \
2023-08-30 14:06:04 -05:00
popToggleColors ( ) ; \
2022-11-10 19:21:01 -05:00
if ( ImGui : : IsItemHovered ( ) ) { \
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Delay/Step Length " ) ) ; \
2022-11-10 19:21:01 -05:00
} \
if ( ImGui : : BeginPopupContextItem ( " IMacroSetP " , ImGuiPopupFlags_MouseButtonLeft ) ) { \
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputScalar ( _ ( " Step Length (ticks)##IMacroSpeed " ) , ImGuiDataType_U8 , & _x . macro - > speed , & _ONE , & _THREE ) ) { \
2022-11-11 00:46:39 -05:00
if ( _x . macro - > speed < 1 ) _x . macro - > speed = 1 ; \
2022-11-10 19:21:01 -05:00
MARK_MODIFIED ; \
} \
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputScalar ( _ ( " Delay##IMacroDelay " ) , ImGuiDataType_U8 , & _x . macro - > delay , & _ONE , & _THREE ) ) { \
2022-11-10 19:21:01 -05:00
MARK_MODIFIED ; \
} \
ImGui : : EndPopup ( ) ; \
}
2023-10-11 03:36:21 -05:00
# define BUTTON_TO_SET_RELEASE(buttonType) \
pushToggleColors ( i . macro - > open & 8 ) ; \
if ( buttonType ( ICON_FA_BOLT " ##IMacroRelMode " ) ) { \
i . macro - > open ^ = 8 ; \
} \
if ( ImGui : : IsItemHovered ( ) ) { \
if ( i . macro - > open & 8 ) { \
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Release mode: Active (jump to release pos) " ) ) ; \
2023-10-11 03:36:21 -05:00
} else { \
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Release mode: Passive (delayed release) " ) ) ; \
2023-10-11 03:36:21 -05:00
} \
} \
popToggleColors ( ) ; \
2025-03-10 12:46:46 -05:00
void FurnaceGUI : : drawMacros ( std : : vector < FurnaceGUIMacroDesc > & macros , FurnaceGUIMacroEditState & state , DivInstrument * ins ) {
2022-11-10 19:21:01 -05:00
int index = 0 ;
2024-09-29 16:36:37 -05:00
int maxMacroLen = 0 ;
2022-11-10 19:21:01 -05:00
float reservedSpace = ( settings . oldMacroVSlider ) ? ( 20.0f * dpiScale + ImGui : : GetStyle ( ) . ItemSpacing . x ) : ImGui : : GetStyle ( ) . ScrollbarSize ;
2024-09-29 16:36:37 -05:00
for ( FurnaceGUIMacroDesc & m : macros ) {
2025-03-10 12:46:46 -05:00
m . ins = ins ;
2024-09-29 16:36:37 -05:00
if ( m . macro - > len > maxMacroLen ) maxMacroLen = m . macro - > len ;
}
2022-11-10 19:21:01 -05:00
switch ( settings . macroLayout ) {
case 0 : {
if ( ImGui : : BeginTable ( " MacroSpace " , 2 ) ) {
2024-06-24 14:56:47 -05:00
float precalcWidth = 0.0f ;
for ( FurnaceGUIMacroDesc & i : macros ) {
float next = ImGui : : CalcTextSize ( i . displayName ) . x + ImGui : : GetStyle ( ) . ItemInnerSpacing . x * 2.0f + ImGui : : CalcTextSize ( ICON_FA_CHEVRON_UP ) . x + ImGui : : GetStyle ( ) . ItemSpacing . x * 2.0f ;
if ( next > precalcWidth ) precalcWidth = next ;
}
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthFixed , MAX ( 120.0f * dpiScale , precalcWidth ) ) ;
2022-11-10 19:21:01 -05:00
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch , 0.0 ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
float lenAvail = ImGui : : GetContentRegionAvail ( ) . x ;
//ImGui::Dummy(ImVec2(120.0f*dpiScale,dpiScale));
2024-09-11 11:52:42 -07:00
if ( settings . autoMacroStepSize = = 0 ) {
2024-07-25 13:18:22 -05:00
ImGui : : SetNextItemWidth ( 120.0f * dpiScale ) ;
if ( ImGui : : InputInt ( " ##MacroPointSize " , & macroPointSize , 1 , 4 ) ) {
if ( macroPointSize < 1 ) macroPointSize = 1 ;
if ( macroPointSize > 256 ) macroPointSize = 256 ;
}
2022-11-10 19:21:01 -05:00
}
ImGui : : TableNextColumn ( ) ;
float availableWidth = ImGui : : GetContentRegionAvail ( ) . x - reservedSpace ;
int totalFit = MIN ( 255 , availableWidth / MAX ( 1 , macroPointSize * dpiScale ) ) ;
2023-02-01 14:16:20 -05:00
int scrollMax = 0 ;
2024-09-11 11:52:42 -07:00
if ( settings . autoMacroStepSize ! = 0 ) totalFit = 1 ;
2023-02-01 14:16:20 -05:00
for ( FurnaceGUIMacroDesc & i : macros ) {
if ( i . macro - > len > scrollMax ) scrollMax = i . macro - > len ;
2024-09-11 11:52:42 -07:00
if ( settings . autoMacroStepSize = = 1 ) {
2024-07-25 13:18:22 -05:00
if ( ( i . macro - > open & 6 ) = = 0 & & totalFit < i . macro - > len ) totalFit = i . macro - > len ;
2024-09-11 11:52:42 -07:00
} else if ( settings . autoMacroStepSize = = 2 ) {
if ( ( i . macro - > open & 6 ) = = 0 & & totalFit < maxMacroLen ) totalFit = maxMacroLen ;
2024-07-25 13:18:22 -05:00
}
2023-02-01 14:16:20 -05:00
}
scrollMax - = totalFit ;
if ( scrollMax < 0 ) scrollMax = 0 ;
if ( macroDragScroll > scrollMax ) {
macroDragScroll = scrollMax ;
2022-11-10 19:21:01 -05:00
}
2023-02-01 14:33:41 -05:00
ImGui : : BeginDisabled ( scrollMax < 1 ) ;
2022-11-10 19:21:01 -05:00
ImGui : : SetNextItemWidth ( availableWidth ) ;
2025-08-12 16:07:37 -05:00
if ( CWSliderInt ( " ##MacroScrollTop " , & macroDragScroll , 0 , scrollMax , " " ) ) {
2022-11-10 19:21:01 -05:00
if ( macroDragScroll < 0 ) macroDragScroll = 0 ;
2023-02-01 14:16:20 -05:00
if ( macroDragScroll > scrollMax ) macroDragScroll = scrollMax ;
2022-08-22 15:59:45 -05:00
}
2023-02-01 14:33:41 -05:00
ImGui : : EndDisabled ( ) ;
2022-08-22 15:59:45 -05:00
2022-11-10 19:21:01 -05:00
// draw macros
for ( FurnaceGUIMacroDesc & i : macros ) {
ImGui : : PushID ( index ) ;
ImGui : : TableNextRow ( ) ;
2022-10-07 04:11:45 -05:00
2022-11-10 19:21:01 -05:00
// description
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , i . displayName ) ;
ImGui : : SameLine ( ) ;
if ( ImGui : : SmallButton ( ( i . macro - > open & 1 ) ? ( ICON_FA_CHEVRON_UP " ##IMacroOpen " ) : ( ICON_FA_CHEVRON_DOWN " ##IMacroOpen " ) ) ) {
i . macro - > open ^ = 1 ;
}
if ( i . macro - > open & 1 ) {
if ( ( i . macro - > open & 6 ) = = 0 ) {
ImGui : : SetNextItemWidth ( lenAvail ) ;
int macroLen = i . macro - > len ;
if ( ImGui : : InputScalar ( " ##IMacroLen " , ImGuiDataType_U8 , & macroLen , & _ONE , & _THREE ) ) { MARK_MODIFIED
if ( macroLen < 0 ) macroLen = 0 ;
if ( macroLen > 255 ) macroLen = 255 ;
i . macro - > len = macroLen ;
}
2022-10-07 04:11:45 -05:00
}
2022-11-10 19:21:01 -05:00
BUTTON_TO_SET_MODE ( ImGui : : Button ) ;
ImGui : : SameLine ( ) ;
2022-11-11 00:46:39 -05:00
BUTTON_TO_SET_PROPS ( i ) ;
2023-10-11 03:36:21 -05:00
if ( ( i . macro - > open & 6 ) = = 0 ) {
ImGui : : SameLine ( ) ;
BUTTON_TO_SET_RELEASE ( ImGui : : Button ) ;
}
2022-11-10 19:21:01 -05:00
// do not change this!
// anything other than a checkbox will look ugly!
// if you really need more than two macro modes please tell me.
if ( i . modeName ! = NULL ) {
bool modeVal = i . macro - > mode ;
String modeName = fmt : : sprintf ( " %s##IMacroMode " , i . modeName ) ;
if ( ImGui : : Checkbox ( modeName . c_str ( ) , & modeVal ) ) {
i . macro - > mode = modeVal ;
}
}
2022-10-07 15:06:04 -05:00
}
2022-10-07 04:11:45 -05:00
2022-11-10 19:21:01 -05:00
// macro area
ImGui : : TableNextColumn ( ) ;
drawMacroEdit ( i , totalFit , availableWidth , index ) ;
ImGui : : PopID ( ) ;
index + + ;
}
2022-10-07 04:11:45 -05:00
2022-11-10 19:21:01 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : TableNextColumn ( ) ;
2023-02-01 14:33:41 -05:00
ImGui : : BeginDisabled ( scrollMax < 1 ) ;
2022-11-10 19:21:01 -05:00
ImGui : : SetNextItemWidth ( availableWidth ) ;
2025-08-12 16:07:37 -05:00
if ( CWSliderInt ( " ##MacroScrollBottom " , & macroDragScroll , 0 , scrollMax , " " ) ) {
2022-11-10 19:21:01 -05:00
if ( macroDragScroll < 0 ) macroDragScroll = 0 ;
2023-02-01 14:16:20 -05:00
if ( macroDragScroll > scrollMax ) macroDragScroll = scrollMax ;
2022-05-06 23:52:26 -05:00
}
2023-02-01 14:33:41 -05:00
ImGui : : EndDisabled ( ) ;
2022-11-10 19:21:01 -05:00
ImGui : : EndTable ( ) ;
2022-05-06 23:52:26 -05:00
}
2022-11-10 19:21:01 -05:00
break ;
2022-05-06 23:52:26 -05:00
}
2022-11-10 19:21:01 -05:00
case 1 : {
2023-08-16 00:43:15 -05:00
ImGui : : Text ( " Tabs " ) ;
2022-11-10 19:21:01 -05:00
break ;
}
case 2 : {
2022-11-11 00:46:39 -05:00
int columns = round ( ImGui : : GetContentRegionAvail ( ) . x / ( 400.0 * dpiScale ) ) ;
int curColumn = 0 ;
2023-01-04 22:59:21 -05:00
if ( columns < 1 ) columns = 1 ;
2022-11-11 00:46:39 -05:00
if ( ImGui : : BeginTable ( " MacroGrid " , columns , ImGuiTableFlags_BordersInner ) ) {
for ( FurnaceGUIMacroDesc & i : macros ) {
if ( curColumn = = 0 ) ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2022-11-10 19:21:01 -05:00
2022-11-11 00:46:39 -05:00
if ( + + curColumn > = columns ) curColumn = 0 ;
float availableWidth = ImGui : : GetContentRegionAvail ( ) . x - reservedSpace ;
int totalFit = i . macro - > len ;
if ( totalFit < 1 ) totalFit = 1 ;
2022-10-07 04:11:45 -05:00
2022-11-11 00:46:39 -05:00
ImGui : : PushID ( index ) ;
2022-10-07 04:11:45 -05:00
2022-11-11 00:46:39 -05:00
ImGui : : TextUnformatted ( i . displayName ) ;
2022-11-10 19:21:01 -05:00
ImGui : : SameLine ( ) ;
2022-11-11 00:46:39 -05:00
if ( ImGui : : SmallButton ( ( i . macro - > open & 1 ) ? ( ICON_FA_CHEVRON_UP " ##IMacroOpen " ) : ( ICON_FA_CHEVRON_DOWN " ##IMacroOpen " ) ) ) {
i . macro - > open ^ = 1 ;
}
2022-10-07 04:11:45 -05:00
2022-11-11 00:46:39 -05:00
if ( i . macro - > open & 1 ) {
2022-11-10 19:21:01 -05:00
ImGui : : SameLine ( ) ;
2022-11-11 00:46:39 -05:00
BUTTON_TO_SET_MODE ( ImGui : : SmallButton ) ;
2022-11-10 19:21:01 -05:00
}
2022-10-07 04:11:45 -05:00
2022-11-11 00:46:39 -05:00
drawMacroEdit ( i , totalFit , availableWidth , index ) ;
2022-10-07 04:11:45 -05:00
2022-11-11 00:46:39 -05:00
if ( i . macro - > open & 1 ) {
if ( ( i . macro - > open & 6 ) = = 0 ) {
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Length " ) ) ;
2022-11-11 00:46:39 -05:00
ImGui : : SameLine ( ) ;
ImGui : : SetNextItemWidth ( 120.0f * dpiScale ) ;
int macroLen = i . macro - > len ;
if ( ImGui : : InputScalar ( " ##IMacroLen " , ImGuiDataType_U8 , & macroLen , & _ONE , & _THREE ) ) { MARK_MODIFIED
if ( macroLen < 0 ) macroLen = 0 ;
if ( macroLen > 255 ) macroLen = 255 ;
i . macro - > len = macroLen ;
}
ImGui : : SameLine ( ) ;
2022-10-07 04:11:45 -05:00
}
2022-11-11 00:46:39 -05:00
BUTTON_TO_SET_PROPS ( i ) ;
2023-10-11 03:36:21 -05:00
if ( ( i . macro - > open & 6 ) = = 0 ) {
ImGui : : SameLine ( ) ;
BUTTON_TO_SET_RELEASE ( ImGui : : Button ) ;
}
2022-11-11 00:46:39 -05:00
if ( i . modeName ! = NULL ) {
bool modeVal = i . macro - > mode ;
String modeName = fmt : : sprintf ( " %s##IMacroMode " , i . modeName ) ;
ImGui : : SameLine ( ) ;
if ( ImGui : : Checkbox ( modeName . c_str ( ) , & modeVal ) ) {
i . macro - > mode = modeVal ;
}
2022-10-07 04:11:45 -05:00
}
2022-11-10 19:21:01 -05:00
}
2022-10-07 04:11:45 -05:00
2022-11-11 00:46:39 -05:00
ImGui : : PopID ( ) ;
index + + ;
}
ImGui : : EndTable ( ) ;
2022-11-10 19:21:01 -05:00
}
break ;
}
case 3 : {
2022-11-11 00:46:39 -05:00
if ( ImGui : : BeginTable ( " MacroList " , 2 , ImGuiTableFlags_Borders ) ) {
2025-03-23 03:30:31 -05:00
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthStretch , 0.2f ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch , 0.8f ) ;
2022-11-11 00:46:39 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
for ( size_t i = 0 ; i < macros . size ( ) ; i + + ) {
2024-09-11 11:52:42 -07:00
// include macro len if non-zero, making particularly clear at-a-glance which macros
// have non-zero len (i.e. are active). and calculate how big we need to be to leave some
// extra space so the column doesn't change size when len is changed under typical
// circumstances (really don't want to move buttons while mouse is being clicked or held).
char buf [ 256 ] ;
if ( macros [ i ] . macro - > len > 0 ) {
2024-09-29 16:36:37 -05:00
snprintf ( buf , 255 , " %s [%d]###%s " , macros [ i ] . displayName , macros [ i ] . macro - > len , macros [ i ] . displayName ) ;
2024-09-11 11:52:42 -07:00
} else {
2024-09-29 16:36:37 -05:00
snprintf ( buf , 255 , " %s " , macros [ i ] . displayName ) ;
2024-09-11 11:52:42 -07:00
}
2025-03-23 03:30:31 -05:00
if ( ImGui : : Selectable ( buf , state . selectedMacro = = ( int ) i ) ) {
2022-11-11 00:46:39 -05:00
state . selectedMacro = i ;
2022-05-06 23:52:26 -05:00
}
}
2022-10-07 15:06:04 -05:00
2022-11-11 00:46:39 -05:00
ImGui : : TableNextColumn ( ) ;
float availableWidth = ImGui : : GetContentRegionAvail ( ) . x - reservedSpace ;
int totalFit = MIN ( 255 , availableWidth / MAX ( 1 , macroPointSize * dpiScale ) ) ;
if ( macroDragScroll > 255 - totalFit ) {
macroDragScroll = 255 - totalFit ;
}
2022-10-07 15:06:04 -05:00
2022-11-11 00:46:39 -05:00
if ( state . selectedMacro < 0 | | state . selectedMacro > = ( int ) macros . size ( ) ) {
state . selectedMacro = 0 ;
}
2022-10-07 15:06:04 -05:00
2022-11-11 00:46:39 -05:00
if ( state . selectedMacro > = 0 & & state . selectedMacro < ( int ) macros . size ( ) ) {
FurnaceGUIMacroDesc & m = macros [ state . selectedMacro ] ;
m . macro - > open | = 1 ;
2022-10-07 15:06:04 -05:00
2023-08-16 00:43:15 -05:00
float availableWidth = ImGui : : GetContentRegionAvail ( ) . x - reservedSpace ;
int totalFit = MIN ( 255 , availableWidth / MAX ( 1 , macroPointSize * dpiScale ) ) ;
int scrollMax = 0 ;
for ( FurnaceGUIMacroDesc & i : macros ) {
if ( i . macro - > len > scrollMax ) scrollMax = i . macro - > len ;
}
2024-09-11 11:52:42 -07:00
if ( settings . autoMacroStepSize = = 1 ) totalFit = MAX ( 1 , m . macro - > len ) ;
else if ( settings . autoMacroStepSize = = 2 ) totalFit = MAX ( 1 , maxMacroLen ) ;
2023-08-16 00:43:15 -05:00
scrollMax - = totalFit ;
if ( scrollMax < 0 ) scrollMax = 0 ;
if ( macroDragScroll > scrollMax ) {
macroDragScroll = scrollMax ;
}
ImGui : : BeginDisabled ( scrollMax < 1 ) ;
ImGui : : SetNextItemWidth ( availableWidth ) ;
if ( CWSliderInt ( " ##MacroScroll " , & macroDragScroll , 0 , scrollMax , " " ) ) {
if ( macroDragScroll < 0 ) macroDragScroll = 0 ;
if ( macroDragScroll > scrollMax ) macroDragScroll = scrollMax ;
}
ImGui : : EndDisabled ( ) ;
2024-09-11 11:52:42 -07:00
if ( settings . autoMacroStepSize = = 0 ) {
2024-07-25 13:18:22 -05:00
ImGui : : SameLine ( ) ;
ImGui : : Button ( ICON_FA_SEARCH_PLUS " ##MacroZoomB " ) ;
if ( ImGui : : BeginPopupContextItem ( " MacroZoomP " , ImGuiPopupFlags_MouseButtonLeft ) ) {
ImGui : : SetNextItemWidth ( 120.0f * dpiScale ) ;
if ( ImGui : : InputInt ( " ##MacroPointSize " , & macroPointSize , 1 , 4 ) ) {
if ( macroPointSize < 1 ) macroPointSize = 1 ;
if ( macroPointSize > 256 ) macroPointSize = 256 ;
}
ImGui : : EndPopup ( ) ;
2023-08-16 00:43:15 -05:00
}
}
m . height = ImGui : : GetContentRegionAvail ( ) . y - ImGui : : GetFontSize ( ) - ImGui : : GetFrameHeightWithSpacing ( ) - ( m . bit30 ? 28.0f : 12.0f ) * dpiScale - ImGui : : GetStyle ( ) . ItemSpacing . y * 3.0f ;
2022-11-11 00:46:39 -05:00
if ( m . height < 10.0f * dpiScale ) m . height = 10.0f * dpiScale ;
m . height / = dpiScale ;
drawMacroEdit ( m , totalFit , availableWidth , index ) ;
2022-10-07 15:06:04 -05:00
2022-11-11 00:46:39 -05:00
if ( m . macro - > open & 1 ) {
2024-09-11 21:46:29 -07:00
bool showLen = ( ( m . macro - > open & 6 ) = = 0 ) ;
int colCount = showLen ? 4 : 3 ;
float availX = ImGui : : GetContentRegionAvail ( ) . x ;
// fairly arbitrary scaling logic
bool shortLabels = ( availX < 600.0f * dpiScale ) ;
2024-09-11 22:11:51 -07:00
float scalarItemWidth = MIN ( ( availX - 90.0f * dpiScale ) / colCount , 120.0f * dpiScale ) ;
2024-09-11 21:46:29 -07:00
if ( ImGui : : BeginTable ( " ##MacroMetaData " , colCount ) ) {
if ( showLen ) ImGui : : TableSetupColumn ( " len " , ImGuiTableColumnFlags_WidthStretch , 0.0 ) ;
ImGui : : TableSetupColumn ( " stepLen " , ImGuiTableColumnFlags_WidthStretch , 0.0 ) ;
ImGui : : TableSetupColumn ( " delay " , ImGuiTableColumnFlags_WidthStretch , 0.0 ) ;
ImGui : : TableSetupColumn ( " buttons " , ImGuiTableColumnFlags_WidthFixed , 0.0 ) ;
ImGui : : TableNextRow ( ) ;
if ( showLen ) {
ImGui : : TableNextColumn ( ) ;
2025-03-23 03:30:31 -05:00
ImGui : : AlignTextToFramePadding ( ) ;
2024-09-11 21:46:29 -07:00
ImGui : : Text ( shortLabels ? _ ( " Len##macroEditLengthShortLabel " ) : _ ( " Length " ) ) ;
if ( shortLabels & & ImGui : : IsItemHovered ( ) ) ImGui : : SetTooltip ( " %s " , _ ( " Length " ) ) ;
ImGui : : SameLine ( ) ;
ImGui : : SetNextItemWidth ( scalarItemWidth ) ;
int macroLen = m . macro - > len ;
if ( ImGui : : InputScalar ( " ##IMacroLen " , ImGuiDataType_U8 , & macroLen , & _ONE , & _THREE ) ) { MARK_MODIFIED
if ( macroLen < 0 ) macroLen = 0 ;
if ( macroLen > 255 ) macroLen = 255 ;
m . macro - > len = macroLen ;
}
2022-11-11 00:46:39 -05:00
}
2024-09-11 21:46:29 -07:00
ImGui : : TableNextColumn ( ) ;
2025-03-23 03:30:31 -05:00
ImGui : : AlignTextToFramePadding ( ) ;
2024-09-11 21:46:29 -07:00
ImGui : : Text ( shortLabels ? _ ( " SLen##macroEditStepLenShortLabel " ) : _ ( " StepLen " ) ) ;
if ( shortLabels & & ImGui : : IsItemHovered ( ) ) ImGui : : SetTooltip ( " %s " , _ ( " StepLen " ) ) ;
2022-11-11 00:46:39 -05:00
ImGui : : SameLine ( ) ;
2024-09-11 21:46:29 -07:00
ImGui : : SetNextItemWidth ( scalarItemWidth ) ;
if ( ImGui : : InputScalar ( " ##IMacroSpeed " , ImGuiDataType_U8 , & m . macro - > speed , & _ONE , & _THREE ) ) {
if ( m . macro - > speed < 1 ) m . macro - > speed = 1 ;
MARK_MODIFIED ;
2023-10-11 03:36:21 -05:00
}
2024-09-11 21:46:29 -07:00
ImGui : : TableNextColumn ( ) ;
2025-03-23 03:30:31 -05:00
ImGui : : AlignTextToFramePadding ( ) ;
2024-09-11 21:46:29 -07:00
ImGui : : Text ( shortLabels ? _ ( " Del##macroEditDelayShortLabel " ) : _ ( " Delay " ) ) ;
if ( shortLabels & & ImGui : : IsItemHovered ( ) ) ImGui : : SetTooltip ( " %s " , _ ( " Delay " ) ) ;
2022-11-11 00:46:39 -05:00
ImGui : : SameLine ( ) ;
2024-09-11 21:46:29 -07:00
ImGui : : SetNextItemWidth ( scalarItemWidth ) ;
if ( ImGui : : InputScalar ( " ##IMacroDelay " , ImGuiDataType_U8 , & m . macro - > delay , & _ONE , & _THREE ) ) {
MARK_MODIFIED ;
2022-11-11 00:46:39 -05:00
}
2024-09-11 21:46:29 -07:00
ImGui : : TableNextColumn ( ) ;
{
FurnaceGUIMacroDesc & i = m ;
BUTTON_TO_SET_MODE ( ImGui : : Button ) ;
if ( ( i . macro - > open & 6 ) = = 0 ) {
ImGui : : SameLine ( ) ;
BUTTON_TO_SET_RELEASE ( ImGui : : Button ) ;
}
}
if ( m . modeName ! = NULL ) {
bool modeVal = m . macro - > mode ;
String modeName = fmt : : sprintf ( " %s##IMacroMode " , m . modeName ) ;
ImGui : : SameLine ( ) ;
if ( ImGui : : Checkbox ( modeName . c_str ( ) , & modeVal ) ) {
m . macro - > mode = modeVal ;
}
2022-11-11 00:46:39 -05:00
}
2024-09-11 21:46:29 -07:00
ImGui : : EndTable ( ) ;
2022-10-07 15:06:04 -05:00
}
2022-11-11 00:46:39 -05:00
} else {
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " The heck? No, this isn't even working correctly... " ) ) ;
2022-05-06 23:52:26 -05:00
}
2022-11-11 00:46:39 -05:00
} else {
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " The only problem with that selectedMacro is that it's a bug... " ) ) ;
2022-05-06 23:52:26 -05:00
}
2022-11-11 00:46:39 -05:00
// goes here
ImGui : : EndTable ( ) ;
2022-05-06 23:52:26 -05:00
}
2022-11-10 19:21:01 -05:00
break ;
2022-05-06 23:52:26 -05:00
}
2022-11-10 19:21:01 -05:00
case 4 : {
ImGui : : Text ( " Single (combo box) " ) ;
break ;
2022-05-06 23:52:26 -05:00
}
}
2022-02-17 13:08:17 -05:00
}
2023-10-12 20:32:00 -05:00
void FurnaceGUI : : alterSampleMap ( int column , int val ) {
2023-04-11 19:41:20 -05:00
if ( curIns < 0 | | curIns > = ( int ) e - > song . ins . size ( ) ) return ;
DivInstrument * ins = e - > song . ins [ curIns ] ;
int sampleMapMin = sampleMapSelStart ;
int sampleMapMax = sampleMapSelEnd ;
if ( sampleMapMin > sampleMapMax ) {
sampleMapMin ^ = sampleMapMax ;
sampleMapMax ^ = sampleMapMin ;
sampleMapMin ^ = sampleMapMax ;
}
for ( int i = sampleMapMin ; i < = sampleMapMax ; i + + ) {
if ( i < 0 | | i > = 120 ) continue ;
2023-10-12 20:32:00 -05:00
if ( sampleMapColumn = = 1 & & column = = 1 ) {
2023-04-11 19:41:20 -05:00
ins - > amiga . noteMap [ i ] . freq = val ;
2023-10-12 20:32:00 -05:00
} else if ( sampleMapColumn = = 0 & & column = = 0 ) {
2023-04-11 19:41:20 -05:00
if ( val < 0 ) {
ins - > amiga . noteMap [ i ] . map = - 1 ;
} else if ( sampleMapDigit > 0 ) {
ins - > amiga . noteMap [ i ] . map * = 10 ;
ins - > amiga . noteMap [ i ] . map + = val ;
} else {
ins - > amiga . noteMap [ i ] . map = val ;
}
if ( ins - > amiga . noteMap [ i ] . map > = ( int ) e - > song . sample . size ( ) ) {
ins - > amiga . noteMap [ i ] . map = ( ( int ) e - > song . sample . size ( ) ) - 1 ;
}
2023-10-12 20:32:00 -05:00
} else if ( sampleMapColumn = = 2 & & column = = 2 ) {
if ( val < 0 ) {
ins - > amiga . noteMap [ i ] . dpcmFreq = - 1 ;
} else if ( sampleMapDigit > 0 ) {
ins - > amiga . noteMap [ i ] . dpcmFreq * = 10 ;
ins - > amiga . noteMap [ i ] . dpcmFreq + = val ;
} else {
ins - > amiga . noteMap [ i ] . dpcmFreq = val ;
}
if ( ins - > amiga . noteMap [ i ] . dpcmFreq > 15 ) {
ins - > amiga . noteMap [ i ] . dpcmFreq % = 10 ;
}
} else if ( sampleMapColumn = = 3 & & column = = 3 ) {
if ( val < 0 ) {
ins - > amiga . noteMap [ i ] . dpcmDelta = - 1 ;
} else if ( sampleMapDigit > 0 ) {
if ( ins - > amiga . noteMap [ i ] . dpcmDelta > 7 ) {
ins - > amiga . noteMap [ i ] . dpcmDelta = val ;
} else {
ins - > amiga . noteMap [ i ] . dpcmDelta < < = 4 ;
ins - > amiga . noteMap [ i ] . dpcmDelta + = val ;
}
} else {
ins - > amiga . noteMap [ i ] . dpcmDelta = val ;
}
2023-04-11 19:41:20 -05:00
}
}
bool advance = false ;
2023-10-12 20:32:00 -05:00
if ( sampleMapColumn = = 1 & & column = = 1 ) {
2023-04-11 19:41:20 -05:00
advance = true ;
2023-10-12 20:32:00 -05:00
} else if ( sampleMapColumn = = 0 & & column = = 0 ) {
2023-04-11 19:41:20 -05:00
int digits = 1 ;
if ( e - > song . sample . size ( ) > = 10 ) digits = 2 ;
if ( e - > song . sample . size ( ) > = 100 ) digits = 3 ;
if ( + + sampleMapDigit > = digits ) {
sampleMapDigit = 0 ;
advance = true ;
}
2023-10-12 20:32:00 -05:00
} else if ( sampleMapColumn = = 2 & & column = = 2 ) {
if ( + + sampleMapDigit > = 2 ) {
sampleMapDigit = 0 ;
advance = true ;
}
} else if ( sampleMapColumn = = 3 & & column = = 3 ) {
if ( + + sampleMapDigit > = 2 ) {
sampleMapDigit = 0 ;
advance = true ;
}
2023-04-11 19:41:20 -05:00
}
if ( advance & & sampleMapMin = = sampleMapMax ) {
sampleMapSelStart + + ;
if ( sampleMapSelStart > 119 ) sampleMapSelStart = 119 ;
sampleMapSelEnd = sampleMapSelStart ;
}
2023-04-12 00:50:31 -05:00
MARK_MODIFIED ;
2023-04-11 19:41:20 -05:00
}
2022-03-17 02:07:46 -05:00
# define DRUM_FREQ(name,db,df,prop) \
ImGui : : TableNextRow ( ) ; \
ImGui : : TableNextColumn ( ) ; \
if ( ins - > type = = DIV_INS_OPLL ) { \
block = ( prop > > 9 ) & 7 ; \
fNum = prop & 511 ; \
} else { \
block = ( prop > > 10 ) & 7 ; \
fNum = prop & 1023 ; \
} \
ImGui : : Text ( name ) ; \
ImGui : : TableNextColumn ( ) ; \
if ( ImGui : : InputInt ( db , & block , 1 , 1 ) ) { \
if ( block < 0 ) block = 0 ; \
if ( block > 7 ) block = 7 ; \
if ( ins - > type = = DIV_INS_OPLL ) { \
prop = ( block < < 9 ) | fNum ; \
} else { \
prop = ( block < < 10 ) | fNum ; \
} \
} \
ImGui : : TableNextColumn ( ) ; \
2023-12-11 15:58:48 -08:00
if ( ImGui : : InputInt ( df , & fNum , 1 , 16 ) ) { \
2022-03-17 02:07:46 -05:00
if ( fNum < 0 ) fNum = 0 ; \
if ( ins - > type = = DIV_INS_OPLL ) { \
if ( fNum > 511 ) fNum = 511 ; \
prop = ( block < < 9 ) | fNum ; \
} else { \
if ( fNum > 1023 ) fNum = 1023 ; \
prop = ( block < < 10 ) | fNum ; \
} \
}
2022-04-02 00:11:44 -05:00
2022-03-27 01:38:24 -05:00
# define CENTER_TEXT(text) \
ImGui : : SetCursorPosX ( ImGui : : GetCursorPosX ( ) + 0.5 * ( ImGui : : GetContentRegionAvail ( ) . x - ImGui : : CalcTextSize ( text ) . x ) ) ;
# define CENTER_VSLIDER \
2022-03-27 18:30:46 -05:00
ImGui : : SetCursorPosX ( ImGui : : GetCursorPosX ( ) + 0.5f * ImGui : : GetContentRegionAvail ( ) . x - 10.0f * dpiScale ) ;
2022-03-27 01:38:24 -05:00
2022-06-13 03:54:42 -05:00
# define CENTER_TEXT_20(text) \
ImGui : : SetCursorPosX ( ImGui : : GetCursorPosX ( ) + 0.5 * ( 20.0f * dpiScale - ImGui : : CalcTextSize ( text ) . x ) ) ;
2022-11-05 19:47:18 -04:00
# define TOOLTIP_TEXT(text) \
if ( ImGui : : IsItemHovered ( ) ) { \
ImGui : : SetTooltip ( " %s " , text ) ; \
}
2022-09-10 23:20:22 -05:00
# define OP_DRAG_POINT \
if ( ImGui : : Button ( ICON_FA_ARROWS ) ) { \
} \
if ( ImGui : : BeginDragDropSource ( ) ) { \
opToMove = i ; \
ImGui : : SetDragDropPayload ( " FUR_OP " , NULL , 0 , ImGuiCond_Once ) ; \
ImGui : : Button ( ICON_FA_ARROWS " ##SysDrag " ) ; \
2022-09-13 03:29:28 -05:00
ImGui : : SameLine ( ) ; \
if ( ImGui : : IsKeyDown ( ImGuiKey_LeftShift ) | | ImGui : : IsKeyDown ( ImGuiKey_RightShift ) ) { \
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " (copying) " ) ) ; \
2022-09-13 03:29:28 -05:00
} else { \
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " (swapping) " ) ) ; \
2022-09-13 03:29:28 -05:00
} \
2022-09-10 23:20:22 -05:00
ImGui : : EndDragDropSource ( ) ; \
} else if ( ImGui : : IsItemHovered ( ) ) { \
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " - drag to swap operator \n - shift-drag to copy operator " ) ) ; \
2022-09-10 23:20:22 -05:00
} \
if ( ImGui : : BeginDragDropTarget ( ) ) { \
const ImGuiPayload * dragItem = ImGui : : AcceptDragDropPayload ( " FUR_OP " ) ; \
if ( dragItem ! = NULL ) { \
if ( dragItem - > IsDataType ( " FUR_OP " ) ) { \
if ( opToMove ! = i & & opToMove > = 0 ) { \
2023-10-14 17:09:18 -03:00
int destOp = ( opCount = = 4 & & ins - > type ! = DIV_INS_OPL_DRUMS & & ins - > type ! = DIV_INS_ESFM ) ? opOrder [ i ] : i ; \
int sourceOp = ( opCount = = 4 & & ins - > type ! = DIV_INS_OPL_DRUMS & & ins - > type ! = DIV_INS_ESFM ) ? opOrder [ opToMove ] : opToMove ; \
2022-09-13 03:29:28 -05:00
if ( ImGui : : IsKeyDown ( ImGuiKey_LeftShift ) | | ImGui : : IsKeyDown ( ImGuiKey_RightShift ) ) { \
2022-09-16 00:04:43 -05:00
e - > lockEngine ( [ ins , destOp , sourceOp ] ( ) { \
ins - > fm . op [ destOp ] = ins - > fm . op [ sourceOp ] ; \
2023-10-14 17:09:18 -03:00
ins - > esfm . op [ destOp ] = ins - > esfm . op [ sourceOp ] ; \
2022-09-13 03:29:28 -05:00
} ) ; \
} else { \
2022-09-16 00:04:43 -05:00
e - > lockEngine ( [ ins , destOp , sourceOp ] ( ) { \
DivInstrumentFM : : Operator origOp = ins - > fm . op [ sourceOp ] ; \
2023-10-14 17:09:18 -03:00
DivInstrumentESFM : : Operator origOpE = ins - > esfm . op [ sourceOp ] ; \
2022-09-16 00:04:43 -05:00
ins - > fm . op [ sourceOp ] = ins - > fm . op [ destOp ] ; \
2023-10-14 17:09:18 -03:00
ins - > esfm . op [ sourceOp ] = ins - > esfm . op [ destOp ] ; \
2022-09-16 00:04:43 -05:00
ins - > fm . op [ destOp ] = origOp ; \
2023-10-14 17:09:18 -03:00
ins - > esfm . op [ destOp ] = origOpE ; \
2022-09-13 03:29:28 -05:00
} ) ; \
} \
2022-09-10 23:20:22 -05:00
PARAMETER ; \
} \
opToMove = - 1 ; \
} \
} \
ImGui : : EndDragDropTarget ( ) ; \
}
2024-08-05 12:28:22 +03:00
void FurnaceGUI : : insTabWavetable ( DivInstrument * ins )
{
if ( ImGui : : BeginTabItem ( _ ( " Wavetable " ) ) ) {
switch ( ins - > type ) {
case DIV_INS_GB :
case DIV_INS_NAMCO :
case DIV_INS_SM8521 :
case DIV_INS_SWAN :
wavePreviewLen = 32 ;
wavePreviewHeight = 15 ;
break ;
case DIV_INS_PCE :
wavePreviewLen = 32 ;
wavePreviewHeight = 31 ;
break ;
case DIV_INS_VBOY :
wavePreviewLen = 32 ;
wavePreviewHeight = 63 ;
break ;
case DIV_INS_SCC :
wavePreviewLen = 32 ;
wavePreviewHeight = 255 ;
break ;
case DIV_INS_FDS :
wavePreviewLen = 64 ;
wavePreviewHeight = 63 ;
break ;
case DIV_INS_N163 :
wavePreviewLen = ins - > n163 . waveLen ;
wavePreviewHeight = 15 ;
break ;
case DIV_INS_X1_010 :
wavePreviewLen = 128 ;
wavePreviewHeight = 255 ;
break ;
case DIV_INS_AMIGA :
case DIV_INS_GBA_DMA :
wavePreviewLen = ins - > amiga . waveLen + 1 ;
wavePreviewHeight = 255 ;
break ;
case DIV_INS_SNES :
wavePreviewLen = ins - > amiga . waveLen + 1 ;
wavePreviewHeight = 15 ;
break ;
case DIV_INS_GBA_MINMOD :
wavePreviewLen = ins - > amiga . waveLen + 1 ;
wavePreviewHeight = 255 ;
break ;
case DIV_INS_SID3 :
wavePreviewLen = 256 ;
wavePreviewHeight = 255 ;
break ;
default :
wavePreviewLen = 32 ;
wavePreviewHeight = 31 ;
break ;
}
2024-11-28 16:59:59 -07:00
if ( ImGui : : Checkbox ( _ ( " Enable synthesizer " ) , & ins - > ws . enabled ) ) { PARAMETER
2024-08-05 12:28:22 +03:00
wavePreviewInit = true ;
}
if ( ins - > ws . enabled ) {
ImGui : : SameLine ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( ins - > ws . effect & 0x80 ) {
if ( ( ins - > ws . effect & 0x7f ) > = DIV_WS_DUAL_MAX ) {
ins - > ws . effect = 0 ;
wavePreviewInit = true ;
}
} else {
if ( ( ins - > ws . effect & 0x7f ) > = DIV_WS_SINGLE_MAX ) {
ins - > ws . effect = 0 ;
wavePreviewInit = true ;
}
}
if ( ImGui : : BeginCombo ( " ##WSEffect " , ( ins - > ws . effect & 0x80 ) ? dualWSEffects [ ins - > ws . effect & 0x7f ] : singleWSEffects [ ins - > ws . effect & 0x7f ] ) ) {
ImGui : : Text ( _ ( " Single-waveform " ) ) ;
ImGui : : Indent ( ) ;
for ( int i = 0 ; i < DIV_WS_SINGLE_MAX ; i + + ) {
2024-11-28 21:42:06 -07:00
if ( ImGui : : Selectable ( _ ( singleWSEffects [ i ] ) ) ) { PARAMETER
2024-08-05 12:28:22 +03:00
ins - > ws . effect = i ;
wavePreviewInit = true ;
}
}
ImGui : : Unindent ( ) ;
ImGui : : Text ( _ ( " Dual-waveform " ) ) ;
ImGui : : Indent ( ) ;
for ( int i = 129 ; i < DIV_WS_DUAL_MAX ; i + + ) {
2024-11-28 21:42:06 -07:00
if ( ImGui : : Selectable ( _ ( dualWSEffects [ i - 128 ] ) ) ) { PARAMETER
2024-08-05 12:28:22 +03:00
ins - > ws . effect = i ;
wavePreviewInit = true ;
}
}
ImGui : : Unindent ( ) ;
ImGui : : EndCombo ( ) ;
}
const bool isSingleWaveFX = ( ins - > ws . effect > = 128 ) ;
if ( ImGui : : BeginTable ( " WSPreview " , isSingleWaveFX ? 3 : 2 ) ) {
DivWavetable * wave1 = e - > getWave ( ins - > ws . wave1 ) ;
DivWavetable * wave2 = e - > getWave ( ins - > ws . wave2 ) ;
if ( wavePreviewInit ) {
wavePreview . init ( ins , wavePreviewLen , wavePreviewHeight , true ) ;
wavePreviewInit = false ;
}
float wavePreview1 [ 257 ] ;
float wavePreview2 [ 257 ] ;
float wavePreview3 [ 257 ] ;
for ( int i = 0 ; i < wave1 - > len ; i + + ) {
if ( wave1 - > data [ i ] > wave1 - > max ) {
wavePreview1 [ i ] = wave1 - > max ;
} else {
wavePreview1 [ i ] = wave1 - > data [ i ] ;
}
}
if ( wave1 - > len > 0 ) {
wavePreview1 [ wave1 - > len ] = wave1 - > data [ wave1 - > len - 1 ] ;
}
for ( int i = 0 ; i < wave2 - > len ; i + + ) {
if ( wave2 - > data [ i ] > wave2 - > max ) {
wavePreview2 [ i ] = wave2 - > max ;
} else {
wavePreview2 [ i ] = wave2 - > data [ i ] ;
}
}
if ( wave2 - > len > 0 ) {
wavePreview2 [ wave2 - > len ] = wave2 - > data [ wave2 - > len - 1 ] ;
}
if ( ins - > ws . enabled & & ( ! wavePreviewPaused | | wavePreviewInit ) ) {
wavePreview . tick ( true ) ;
WAKE_UP ;
}
for ( int i = 0 ; i < wavePreviewLen ; i + + ) {
wavePreview3 [ i ] = wavePreview . output [ i ] ;
}
if ( wavePreviewLen > 0 ) {
wavePreview3 [ wavePreviewLen ] = wavePreview3 [ wavePreviewLen - 1 ] ;
}
float ySize = ( isSingleWaveFX ? 96.0f : 128.0f ) * dpiScale ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImVec2 size1 = ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , ySize ) ;
PlotNoLerp ( " ##WaveformP1 " , wavePreview1 , wave1 - > len + 1 , 0 , " Wave 1 " , 0 , wave1 - > max , size1 ) ;
if ( isSingleWaveFX ) {
ImGui : : TableNextColumn ( ) ;
ImVec2 size2 = ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , ySize ) ;
PlotNoLerp ( " ##WaveformP2 " , wavePreview2 , wave2 - > len + 1 , 0 , " Wave 2 " , 0 , wave2 - > max , size2 ) ;
}
ImGui : : TableNextColumn ( ) ;
ImVec2 size3 = ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , ySize ) ;
PlotNoLerp ( " ##WaveformP3 " , wavePreview3 , wavePreviewLen + 1 , 0 , " Result " , 0 , wavePreviewHeight , size3 ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
if ( ins - > std . waveMacro . len > 0 ) {
ImGui : : PushStyleColor ( ImGuiCol_Text , uiColors [ GUI_COLOR_WARNING ] ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " Wave 1 " ) ) ;
ImGui : : SameLine ( ) ;
ImGui : : Text ( ICON_FA_EXCLAMATION_TRIANGLE ) ;
ImGui : : PopStyleColor ( ) ;
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " waveform macro is controlling wave 1! \n this value will be ineffective. " ) ) ;
}
} else {
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " Wave 1 " ) ) ;
}
ImGui : : SameLine ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
2024-11-28 21:42:06 -07:00
if ( ImGui : : InputInt ( " ##SelWave1 " , & ins - > ws . wave1 , 1 , 4 ) ) { PARAMETER
2024-08-05 12:28:22 +03:00
if ( ins - > ws . wave1 < 0 ) ins - > ws . wave1 = 0 ;
if ( ins - > ws . wave1 > = ( int ) e - > song . wave . size ( ) ) ins - > ws . wave1 = e - > song . wave . size ( ) - 1 ;
wavePreviewInit = true ;
}
if ( ins - > std . waveMacro . len > 0 ) {
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " waveform macro is controlling wave 1! \n this value will be ineffective. " ) ) ;
}
}
if ( isSingleWaveFX ) {
ImGui : : TableNextColumn ( ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " Wave 2 " ) ) ;
ImGui : : SameLine ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
2024-11-28 21:42:06 -07:00
if ( ImGui : : InputInt ( " ##SelWave2 " , & ins - > ws . wave2 , 1 , 4 ) ) { PARAMETER
2024-08-05 12:28:22 +03:00
if ( ins - > ws . wave2 < 0 ) ins - > ws . wave2 = 0 ;
if ( ins - > ws . wave2 > = ( int ) e - > song . wave . size ( ) ) ins - > ws . wave2 = e - > song . wave . size ( ) - 1 ;
wavePreviewInit = true ;
}
}
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : Button ( wavePreviewPaused ? ( ICON_FA_PLAY " ##WSPause " ) : ( ICON_FA_PAUSE " ##WSPause " ) ) ) {
wavePreviewPaused = ! wavePreviewPaused ;
}
if ( ImGui : : IsItemHovered ( ) ) {
if ( wavePreviewPaused ) {
ImGui : : SetTooltip ( _ ( " Resume preview " ) ) ;
} else {
ImGui : : SetTooltip ( _ ( " Pause preview " ) ) ;
}
}
ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( ICON_FA_REPEAT " ##WSRestart " ) ) {
wavePreviewInit = true ;
}
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " Restart preview " ) ) ;
}
ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( ICON_FA_UPLOAD " ##WSCopy " ) ) {
curWave = e - > addWave ( ) ;
if ( curWave = = - 1 ) {
showError ( _ ( " too many wavetables! " ) ) ;
} else {
wantScrollListWave = true ;
MARK_MODIFIED ;
RESET_WAVE_MACRO_ZOOM ;
nextWindow = GUI_WINDOW_WAVE_EDIT ;
DivWavetable * copyWave = e - > song . wave [ curWave ] ;
copyWave - > len = wavePreviewLen ;
copyWave - > max = wavePreviewHeight ;
memcpy ( copyWave - > data , wavePreview . output , 256 * sizeof ( int ) ) ;
}
}
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " Copy to new wavetable " ) ) ;
}
ImGui : : SameLine ( ) ;
ImGui : : Text ( " (%d× %d) " , wavePreviewLen , wavePreviewHeight + 1 ) ;
ImGui : : EndTable ( ) ;
}
2024-11-28 21:42:06 -07:00
if ( ImGui : : InputScalar ( _ ( " Update Rate " ) , ImGuiDataType_U8 , & ins - > ws . rateDivider , & _ONE , & _EIGHT ) ) { PARAMETER
2024-08-05 12:28:22 +03:00
wavePreviewInit = true ;
}
int speed = ins - > ws . speed + 1 ;
2024-11-28 21:42:06 -07:00
if ( ImGui : : InputInt ( _ ( " Speed " ) , & speed , 1 , 8 ) ) { PARAMETER
2024-08-05 12:28:22 +03:00
if ( speed < 1 ) speed = 1 ;
if ( speed > 256 ) speed = 256 ;
ins - > ws . speed = speed - 1 ;
wavePreviewInit = true ;
}
2024-11-28 21:42:06 -07:00
if ( ImGui : : InputScalar ( _ ( " Amount " ) , ImGuiDataType_U8 , & ins - > ws . param1 , & _ONE , & _EIGHT ) ) { PARAMETER
2024-08-05 12:28:22 +03:00
wavePreviewInit = true ;
}
if ( ins - > ws . effect = = DIV_WS_PHASE_MOD ) {
2024-11-28 21:42:06 -07:00
if ( ImGui : : InputScalar ( _ ( " Power " ) , ImGuiDataType_U8 , & ins - > ws . param2 , & _ONE , & _EIGHT ) ) { PARAMETER
2024-08-05 12:28:22 +03:00
wavePreviewInit = true ;
}
}
2024-11-28 21:42:06 -07:00
if ( ImGui : : Checkbox ( _ ( " Global " ) , & ins - > ws . global ) ) { PARAMETER
2024-08-05 12:28:22 +03:00
wavePreviewInit = true ;
}
} else {
ImGui : : TextWrapped ( _ ( " wavetable synthesizer disabled. \n use the Waveform macro to set the wave for this instrument. " ) ) ;
}
ImGui : : EndTabItem ( ) ;
}
}
2023-10-12 19:52:44 -05:00
void FurnaceGUI : : insTabSample ( DivInstrument * ins ) {
2024-05-26 19:31:17 -05:00
const char * sampleTabName = _ ( " Sample " ) ;
if ( ins - > type = = DIV_INS_NES ) sampleTabName = _ ( " DPCM " ) ;
2023-10-12 19:52:44 -05:00
if ( ImGui : : BeginTabItem ( sampleTabName ) ) {
2023-10-13 19:57:36 -05:00
if ( ins - > type = = DIV_INS_NES & & e - > song . oldDPCM ) {
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " new DPCM features disabled (compatibility)! " ) ) ;
if ( ImGui : : Button ( _ ( " click here to enable them. " ) ) ) {
2023-10-13 19:57:36 -05:00
e - > song . oldDPCM = false ;
MARK_MODIFIED ;
}
ImGui : : EndTabItem ( ) ;
return ;
}
2023-10-12 19:52:44 -05:00
String sName ;
bool wannaOpenSMPopup = false ;
if ( ins - > amiga . initSample < 0 | | ins - > amiga . initSample > = e - > song . sampleLen ) {
2024-05-26 19:31:17 -05:00
sName = _ ( " none selected " ) ;
2023-10-12 19:52:44 -05:00
} else {
sName = e - > song . sample [ ins - > amiga . initSample ] - > name ;
}
if ( ins - > type = = DIV_INS_PCE | |
ins - > type = = DIV_INS_MIKEY | |
ins - > type = = DIV_INS_X1_010 | |
ins - > type = = DIV_INS_SWAN | |
ins - > type = = DIV_INS_AY | |
ins - > type = = DIV_INS_AY8930 | |
ins - > type = = DIV_INS_VRC6 | |
2024-02-11 11:49:20 +09:00
ins - > type = = DIV_INS_SU | |
2024-08-09 14:30:45 +03:00
ins - > type = = DIV_INS_NDS | |
2024-09-13 23:46:03 -05:00
ins - > type = = DIV_INS_SUPERVISION | |
2024-08-09 14:30:45 +03:00
ins - > type = = DIV_INS_SID3 ) {
2024-05-26 19:31:17 -05:00
P ( ImGui : : Checkbox ( _ ( " Use sample " ) , & ins - > amiga . useSample ) ) ;
2023-10-12 19:52:44 -05:00
if ( ins - > type = = DIV_INS_X1_010 ) {
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputInt ( _ ( " Sample bank slot##BANKSLOT " ) , & ins - > x1_010 . bankSlot , 1 , 4 ) ) { PARAMETER
2023-10-12 19:52:44 -05:00
if ( ins - > x1_010 . bankSlot < 0 ) ins - > x1_010 . bankSlot = 0 ;
if ( ins - > x1_010 . bankSlot > = 7 ) ins - > x1_010 . bankSlot = 7 ;
2025-09-22 15:54:48 +09:00
notifySampleChange = true ;
2023-10-12 19:52:44 -05:00
}
}
}
ImGui : : AlignTextToFramePadding ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Sample " ) ) ;
2023-10-12 19:52:44 -05:00
ImGui : : SameLine ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( ImGui : : BeginCombo ( " ##ISample " , sName . c_str ( ) ) ) {
String id ;
for ( int i = 0 ; i < e - > song . sampleLen ; i + + ) {
id = fmt : : sprintf ( " %d: %s " , i , e - > song . sample [ i ] - > name ) ;
if ( ImGui : : Selectable ( id . c_str ( ) , ins - > amiga . initSample = = i ) ) { PARAMETER
ins - > amiga . initSample = i ;
2025-09-22 15:54:48 +09:00
notifySampleChange = true ;
2023-10-12 19:52:44 -05:00
}
}
ImGui : : EndCombo ( ) ;
}
// Wavetable
2024-03-16 14:59:02 +07:00
if ( ins - > type = = DIV_INS_AMIGA | | ins - > type = = DIV_INS_SNES | | ins - > type = = DIV_INS_GBA_DMA | | ins - > type = = DIV_INS_GBA_MINMOD ) {
2024-05-26 19:31:17 -05:00
const char * useWaveText = ins - > type = = DIV_INS_AMIGA ? _ ( " Use wavetable (Amiga/Generic DAC only) " ) : _ ( " Use wavetable " ) ;
2023-10-12 19:52:44 -05:00
ImGui : : BeginDisabled ( ins - > amiga . useNoteMap ) ;
2024-01-10 11:17:36 +07:00
P ( ImGui : : Checkbox ( useWaveText , & ins - > amiga . useWave ) ) ;
2023-10-12 19:52:44 -05:00
if ( ins - > amiga . useWave ) {
int len = ins - > amiga . waveLen + 1 ;
int origLen = len ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputInt ( _ ( " Width " ) , & len , 2 , 16 ) ) {
2024-01-10 11:17:36 +07:00
if ( ins - > type = = DIV_INS_SNES | | ins - > type = = DIV_INS_GBA_DMA ) {
2023-10-12 19:52:44 -05:00
if ( len < 16 ) len = 16 ;
if ( len > 256 ) len = 256 ;
if ( len > origLen ) {
ins - > amiga . waveLen = ( ( len + 15 ) & ( ~ 15 ) ) - 1 ;
} else {
ins - > amiga . waveLen = ( len & ( ~ 15 ) ) - 1 ;
}
} else {
if ( len < 2 ) len = 2 ;
if ( len > 256 ) len = 256 ;
ins - > amiga . waveLen = ( len & ( ~ 1 ) ) - 1 ;
}
PARAMETER
}
}
ImGui : : EndDisabled ( ) ;
2025-10-04 20:25:21 +04:00
} else {
ins - > amiga . useWave = false ;
2023-10-12 19:52:44 -05:00
}
// Note map
ImGui : : BeginDisabled ( ins - > amiga . useWave ) ;
2024-05-26 19:31:17 -05:00
P ( ImGui : : Checkbox ( _ ( " Use sample map " ) , & ins - > amiga . useNoteMap ) ) ;
2025-08-27 22:52:19 +09:00
if ( ( ins - > type = = DIV_INS_MULTIPCM ) & & ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " Only for OPL4 PCM. " ) ) ;
}
2023-10-12 19:52:44 -05:00
if ( ins - > amiga . useNoteMap ) {
if ( ImGui : : IsMouseClicked ( ImGuiMouseButton_Left ) & & ImGui : : IsWindowHovered ( ImGuiHoveredFlags_ChildWindows ) ) sampleMapFocused = false ;
if ( curWindowLast ! = GUI_WINDOW_INS_EDIT ) sampleMapFocused = false ;
if ( ! sampleMapFocused ) sampleMapDigit = 0 ;
if ( ImGui : : BeginTable ( " NoteMap " , ( ins - > type = = DIV_INS_NES ) ? 5 : 4 , ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_SizingStretchSame ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthFixed ) ;
if ( ins - > type = = DIV_INS_NES ) ImGui : : TableSetupColumn ( " c3 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " c4 " , ImGuiTableColumnFlags_WidthStretch ) ;
ImGui : : TableSetupScrollFreeze ( 0 , 1 ) ;
ImGui : : TableNextRow ( ImGuiTableRowFlags_Headers ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " # " ) ;
if ( ins - > type = = DIV_INS_NES ) {
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " pitch " ) ) ;
2023-10-12 19:52:44 -05:00
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " delta " ) ) ;
2023-10-12 19:52:44 -05:00
} else {
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " note " ) ) ;
2023-10-12 19:52:44 -05:00
}
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " sample name " ) ) ;
2023-10-12 19:52:44 -05:00
int sampleMapMin = sampleMapSelStart ;
int sampleMapMax = sampleMapSelEnd ;
if ( sampleMapMin > sampleMapMax ) {
sampleMapMin ^ = sampleMapMax ;
sampleMapMax ^ = sampleMapMin ;
sampleMapMin ^ = sampleMapMax ;
}
ImGui : : PushStyleColor ( ImGuiCol_Header , ImGui : : GetColorU32 ( ImGuiCol_HeaderHovered ) ) ;
ImGui : : PushStyleColor ( ImGuiCol_HeaderActive , ImGui : : GetColorU32 ( ImGuiCol_HeaderHovered ) ) ;
for ( int i = 0 ; i < 120 ; i + + ) {
DivInstrumentAmiga : : SampleMap & sampleMap = ins - > amiga . noteMap [ i ] ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : TableSetBgColor ( ImGuiTableBgTarget_CellBg , ImGui : : GetColorU32 ( ImGuiCol_TableHeaderBg ) ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( " %s " , noteNames [ 60 + i ] ) ;
ImGui : : TableNextColumn ( ) ;
if ( sampleMap . map < 0 | | sampleMap . map > = e - > song . sampleLen ) {
sName = fmt : : sprintf ( " ---##SM%d " , i ) ;
sampleMap . map = - 1 ;
} else {
sName = fmt : : sprintf ( " %3d##SM%d " , sampleMap . map , i ) ;
}
ImGui : : PushFont ( patFont ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : CalcTextSize ( " 00000 " ) . x ) ;
ImGui : : Selectable ( sName . c_str ( ) , ( sampleMapWaitingInput & & sampleMapColumn = = 0 & & i > = sampleMapMin & & i < = sampleMapMax ) ) ;
if ( ImGui : : IsItemClicked ( ImGuiMouseButton_Left ) ) {
sampleMapFocused = true ;
sampleMapColumn = 0 ;
sampleMapDigit = 0 ;
sampleMapSelStart = i ;
sampleMapSelEnd = i ;
sampleMapMin = sampleMapSelStart ;
sampleMapMax = sampleMapSelEnd ;
if ( sampleMapMin > sampleMapMax ) {
sampleMapMin ^ = sampleMapMax ;
sampleMapMax ^ = sampleMapMin ;
sampleMapMin ^ = sampleMapMax ;
}
ImGui : : InhibitInertialScroll ( ) ;
}
if ( sampleMapFocused & & ImGui : : IsItemHovered ( ImGuiHoveredFlags_AllowWhenBlockedByActiveItem ) & & ImGui : : IsMouseDown ( ImGuiMouseButton_Left ) ) {
sampleMapSelEnd = i ;
}
if ( ImGui : : IsItemClicked ( ImGuiMouseButton_Right ) ) {
if ( sampleMapSelStart = = sampleMapSelEnd ) {
sampleMapFocused = true ;
sampleMapColumn = 0 ;
sampleMapDigit = 0 ;
sampleMapSelStart = i ;
sampleMapSelEnd = i ;
sampleMapMin = sampleMapSelStart ;
sampleMapMax = sampleMapSelEnd ;
if ( sampleMapMin > sampleMapMax ) {
sampleMapMin ^ = sampleMapMax ;
sampleMapMax ^ = sampleMapMin ;
sampleMapMin ^ = sampleMapMax ;
}
}
if ( sampleMapFocused ) {
wannaOpenSMPopup = true ;
}
}
ImGui : : PopFont ( ) ;
if ( ins - > type = = DIV_INS_NES ) {
// pitch
ImGui : : TableNextColumn ( ) ;
ImGui : : PushFont ( patFont ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : CalcTextSize ( " 0000 " ) . x ) ;
2023-10-12 20:32:00 -05:00
if ( sampleMap . dpcmFreq < 0 ) {
2023-10-13 20:16:51 -05:00
sName = fmt : : sprintf ( " -- ##SD1%d " , i ) ;
2023-10-12 20:32:00 -05:00
} else {
2023-10-13 20:16:51 -05:00
sName = fmt : : sprintf ( " %2d ##SD1%d " , sampleMap . dpcmFreq , i ) ;
2023-10-12 20:32:00 -05:00
}
ImGui : : Selectable ( sName . c_str ( ) , ( sampleMapWaitingInput & & sampleMapColumn = = 2 & & i > = sampleMapMin & & i < = sampleMapMax ) ) ;
2023-10-12 19:52:44 -05:00
if ( ImGui : : IsItemClicked ( ImGuiMouseButton_Left ) ) {
sampleMapFocused = true ;
2023-10-12 20:32:00 -05:00
sampleMapColumn = 2 ;
2023-10-12 19:52:44 -05:00
sampleMapDigit = 0 ;
sampleMapSelStart = i ;
sampleMapSelEnd = i ;
sampleMapMin = sampleMapSelStart ;
sampleMapMax = sampleMapSelEnd ;
if ( sampleMapMin > sampleMapMax ) {
sampleMapMin ^ = sampleMapMax ;
sampleMapMax ^ = sampleMapMin ;
sampleMapMin ^ = sampleMapMax ;
}
ImGui : : InhibitInertialScroll ( ) ;
}
if ( sampleMapFocused & & ImGui : : IsItemHovered ( ImGuiHoveredFlags_AllowWhenBlockedByActiveItem ) & & ImGui : : IsMouseDown ( ImGuiMouseButton_Left ) ) {
sampleMapSelEnd = i ;
}
if ( ImGui : : IsItemClicked ( ImGuiMouseButton_Right ) ) {
if ( sampleMapSelStart = = sampleMapSelEnd ) {
sampleMapFocused = true ;
2023-10-12 20:32:00 -05:00
sampleMapColumn = 2 ;
2023-10-12 19:52:44 -05:00
sampleMapDigit = 0 ;
sampleMapSelStart = i ;
sampleMapSelEnd = i ;
sampleMapMin = sampleMapSelStart ;
sampleMapMax = sampleMapSelEnd ;
if ( sampleMapMin > sampleMapMax ) {
sampleMapMin ^ = sampleMapMax ;
sampleMapMax ^ = sampleMapMin ;
sampleMapMin ^ = sampleMapMax ;
}
}
if ( sampleMapFocused ) {
wannaOpenSMPopup = true ;
}
}
ImGui : : PopFont ( ) ;
// delta
ImGui : : TableNextColumn ( ) ;
ImGui : : PushFont ( patFont ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : CalcTextSize ( " 0000 " ) . x ) ;
2023-10-12 20:32:00 -05:00
if ( sampleMap . dpcmDelta < 0 ) {
2023-10-13 20:16:51 -05:00
sName = fmt : : sprintf ( " -- ##SD2%d " , i ) ;
2023-10-12 20:32:00 -05:00
} else {
2023-10-13 20:16:51 -05:00
sName = fmt : : sprintf ( " %2X ##SD2%d " , sampleMap . dpcmDelta , i ) ;
2023-10-12 20:32:00 -05:00
}
ImGui : : Selectable ( sName . c_str ( ) , ( sampleMapWaitingInput & & sampleMapColumn = = 3 & & i > = sampleMapMin & & i < = sampleMapMax ) ) ;
2023-10-12 19:52:44 -05:00
if ( ImGui : : IsItemClicked ( ImGuiMouseButton_Left ) ) {
sampleMapFocused = true ;
2023-10-12 20:32:00 -05:00
sampleMapColumn = 3 ;
2023-10-12 19:52:44 -05:00
sampleMapDigit = 0 ;
sampleMapSelStart = i ;
sampleMapSelEnd = i ;
sampleMapMin = sampleMapSelStart ;
sampleMapMax = sampleMapSelEnd ;
if ( sampleMapMin > sampleMapMax ) {
sampleMapMin ^ = sampleMapMax ;
sampleMapMax ^ = sampleMapMin ;
sampleMapMin ^ = sampleMapMax ;
}
ImGui : : InhibitInertialScroll ( ) ;
}
if ( sampleMapFocused & & ImGui : : IsItemHovered ( ImGuiHoveredFlags_AllowWhenBlockedByActiveItem ) & & ImGui : : IsMouseDown ( ImGuiMouseButton_Left ) ) {
sampleMapSelEnd = i ;
}
if ( ImGui : : IsItemClicked ( ImGuiMouseButton_Right ) ) {
if ( sampleMapSelStart = = sampleMapSelEnd ) {
sampleMapFocused = true ;
2023-10-12 20:32:00 -05:00
sampleMapColumn = 3 ;
2023-10-12 19:52:44 -05:00
sampleMapDigit = 0 ;
sampleMapSelStart = i ;
sampleMapSelEnd = i ;
sampleMapMin = sampleMapSelStart ;
sampleMapMax = sampleMapSelEnd ;
if ( sampleMapMin > sampleMapMax ) {
sampleMapMin ^ = sampleMapMax ;
sampleMapMax ^ = sampleMapMin ;
sampleMapMin ^ = sampleMapMax ;
}
}
if ( sampleMapFocused ) {
wannaOpenSMPopup = true ;
}
}
ImGui : : PopFont ( ) ;
} else {
ImGui : : TableNextColumn ( ) ;
sName = " ??? " ;
if ( ( sampleMap . freq + 60 ) > 0 & & ( sampleMap . freq + 60 ) < 180 ) {
sName = noteNames [ sampleMap . freq + 60 ] ;
}
sName + = fmt : : sprintf ( " ##SN%d " , i ) ;
ImGui : : PushFont ( patFont ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : CalcTextSize ( " 00000 " ) . x ) ;
ImGui : : Selectable ( sName . c_str ( ) , ( sampleMapWaitingInput & & sampleMapColumn = = 1 & & i > = sampleMapMin & & i < = sampleMapMax ) ) ;
if ( ImGui : : IsItemClicked ( ImGuiMouseButton_Left ) ) {
sampleMapFocused = true ;
sampleMapColumn = 1 ;
sampleMapDigit = 0 ;
sampleMapSelStart = i ;
sampleMapSelEnd = i ;
sampleMapMin = sampleMapSelStart ;
sampleMapMax = sampleMapSelEnd ;
if ( sampleMapMin > sampleMapMax ) {
sampleMapMin ^ = sampleMapMax ;
sampleMapMax ^ = sampleMapMin ;
sampleMapMin ^ = sampleMapMax ;
}
ImGui : : InhibitInertialScroll ( ) ;
}
if ( sampleMapFocused & & ImGui : : IsItemHovered ( ImGuiHoveredFlags_AllowWhenBlockedByActiveItem ) & & ImGui : : IsMouseDown ( ImGuiMouseButton_Left ) ) {
sampleMapSelEnd = i ;
}
if ( ImGui : : IsItemClicked ( ImGuiMouseButton_Right ) ) {
if ( sampleMapSelStart = = sampleMapSelEnd ) {
sampleMapFocused = true ;
sampleMapColumn = 1 ;
sampleMapDigit = 0 ;
sampleMapSelStart = i ;
sampleMapSelEnd = i ;
sampleMapMin = sampleMapSelStart ;
sampleMapMax = sampleMapSelEnd ;
if ( sampleMapMin > sampleMapMax ) {
sampleMapMin ^ = sampleMapMax ;
sampleMapMax ^ = sampleMapMin ;
sampleMapMin ^ = sampleMapMax ;
}
}
if ( sampleMapFocused ) {
wannaOpenSMPopup = true ;
}
}
ImGui : : PopFont ( ) ;
}
ImGui : : TableNextColumn ( ) ;
String prevName = " --- " ;
if ( sampleMap . map > = 0 & & sampleMap . map < e - > song . sampleLen ) {
prevName = e - > song . sample [ sampleMap . map ] - > name ;
}
ImGui : : PushID ( i + 2 ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( ImGui : : BeginCombo ( " ##SMSample " , prevName . c_str ( ) ) ) {
if ( ImGui : : Selectable ( " --- " ) ) {
sampleMap . map = - 1 ;
}
for ( int k = 0 ; k < e - > song . sampleLen ; k + + ) {
String itemName = fmt : : sprintf ( " %d: %s " , k , e - > song . sample [ k ] - > name ) ;
if ( ImGui : : Selectable ( itemName . c_str ( ) ) ) {
sampleMap . map = k ;
}
}
ImGui : : EndCombo ( ) ;
}
ImGui : : PopID ( ) ;
}
ImGui : : PopStyleColor ( 2 ) ;
ImGui : : EndTable ( ) ;
}
} else {
sampleMapFocused = false ;
}
ImGui : : EndDisabled ( ) ;
if ( wannaOpenSMPopup ) {
ImGui : : OpenPopup ( " SampleMapUtils " ) ;
}
if ( ImGui : : BeginPopup ( " SampleMapUtils " , ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings ) ) {
if ( sampleMapSelStart = = sampleMapSelEnd & & sampleMapSelStart > = 0 & & sampleMapSelStart < 120 ) {
if ( ins - > type = = DIV_INS_NES ) {
2024-05-26 19:31:17 -05:00
if ( ImGui : : MenuItem ( _ ( " set entire map to this pitch " ) ) ) {
2023-10-13 19:57:36 -05:00
if ( sampleMapSelStart > = 0 & & sampleMapSelStart < 120 ) {
for ( int i = 0 ; i < 120 ; i + + ) {
if ( i = = sampleMapSelStart ) continue ;
ins - > amiga . noteMap [ i ] . dpcmFreq = ins - > amiga . noteMap [ sampleMapSelStart ] . dpcmFreq ;
}
}
2023-10-12 19:52:44 -05:00
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : MenuItem ( _ ( " set entire map to this delta counter value " ) ) ) {
2023-10-13 19:57:36 -05:00
if ( sampleMapSelStart > = 0 & & sampleMapSelStart < 120 ) {
for ( int i = 0 ; i < 120 ; i + + ) {
if ( i = = sampleMapSelStart ) continue ;
ins - > amiga . noteMap [ i ] . dpcmDelta = ins - > amiga . noteMap [ sampleMapSelStart ] . dpcmDelta ;
}
}
2023-10-12 19:52:44 -05:00
}
} else {
2024-05-26 19:31:17 -05:00
if ( ImGui : : MenuItem ( _ ( " set entire map to this note " ) ) ) {
2023-10-12 19:52:44 -05:00
if ( sampleMapSelStart > = 0 & & sampleMapSelStart < 120 ) {
for ( int i = 0 ; i < 120 ; i + + ) {
if ( i = = sampleMapSelStart ) continue ;
ins - > amiga . noteMap [ i ] . freq = ins - > amiga . noteMap [ sampleMapSelStart ] . freq ;
}
}
}
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : MenuItem ( _ ( " set entire map to this sample " ) ) ) {
2023-10-12 19:52:44 -05:00
if ( sampleMapSelStart > = 0 & & sampleMapSelStart < 120 ) {
for ( int i = 0 ; i < 120 ; i + + ) {
if ( i = = sampleMapSelStart ) continue ;
ins - > amiga . noteMap [ i ] . map = ins - > amiga . noteMap [ sampleMapSelStart ] . map ;
}
}
}
}
if ( ins - > type = = DIV_INS_NES ) {
2024-05-26 19:31:17 -05:00
if ( ImGui : : MenuItem ( _ ( " reset pitches " ) ) ) {
2023-10-13 19:57:36 -05:00
for ( int i = 0 ; i < 120 ; i + + ) {
ins - > amiga . noteMap [ i ] . dpcmFreq = 15 ;
}
2023-10-12 19:52:44 -05:00
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : MenuItem ( _ ( " clear delta counter values " ) ) ) {
2023-10-13 19:57:36 -05:00
for ( int i = 0 ; i < 120 ; i + + ) {
ins - > amiga . noteMap [ i ] . dpcmDelta = - 1 ;
}
2023-10-12 19:52:44 -05:00
}
} else {
2024-05-26 19:31:17 -05:00
if ( ImGui : : MenuItem ( _ ( " reset notes " ) ) ) {
2023-10-12 19:52:44 -05:00
for ( int i = 0 ; i < 120 ; i + + ) {
ins - > amiga . noteMap [ i ] . freq = i ;
}
}
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : MenuItem ( _ ( " clear map samples " ) ) ) {
2023-10-12 19:52:44 -05:00
for ( int i = 0 ; i < 120 ; i + + ) {
ins - > amiga . noteMap [ i ] . map = - 1 ;
}
}
ImGui : : EndPopup ( ) ;
}
ImGui : : EndTabItem ( ) ;
} else {
sampleMapFocused = false ;
}
}
2024-07-25 19:59:21 -05:00
void FurnaceGUI : : insTabFMModernHeader ( DivInstrument * ins ) {
ImGui : : TableNextRow ( ImGuiTableRowFlags_Headers ) ;
ImGui : : TableNextColumn ( ) ;
if ( ins - > type = = DIV_INS_ESFM ) {
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( ESFM_SHORT_NAME ( ESFM_MODIN ) ) ;
ImGui : : TextUnformatted ( ESFM_SHORT_NAME ( ESFM_MODIN ) ) ;
TOOLTIP_TEXT ( ESFM_LONG_NAME ( ESFM_MODIN ) ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( ESFM_SHORT_NAME ( ESFM_DELAY ) ) ;
ImGui : : TextUnformatted ( ESFM_SHORT_NAME ( ESFM_DELAY ) ) ;
TOOLTIP_TEXT ( ESFM_LONG_NAME ( ESFM_DELAY ) ) ;
}
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( FM_SHORT_NAME ( FM_AR ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_AR ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_AR ) ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( FM_SHORT_NAME ( FM_DR ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_DR ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_DR ) ) ;
if ( settings . susPosition = = 0 ) {
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( FM_SHORT_NAME ( FM_SL ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_SL ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_SL ) ) ;
}
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) {
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( FM_SHORT_NAME ( FM_D2R ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_D2R ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_D2R ) ) ;
}
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( FM_SHORT_NAME ( FM_RR ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_RR ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_RR ) ) ;
if ( settings . susPosition = = 1 ) {
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( FM_SHORT_NAME ( FM_SL ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_SL ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_SL ) ) ;
}
ImGui : : TableNextColumn ( ) ;
if ( settings . susPosition = = 2 ) {
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( FM_SHORT_NAME ( FM_SL ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_SL ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_SL ) ) ;
}
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( FM_SHORT_NAME ( FM_TL ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_TL ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_TL ) ) ;
if ( settings . susPosition = = 3 ) {
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( FM_SHORT_NAME ( FM_SL ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_SL ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_SL ) ) ;
}
ImGui : : TableNextColumn ( ) ;
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) {
CENTER_TEXT ( FM_SHORT_NAME ( FM_RS ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_RS ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_RS ) ) ;
} else {
CENTER_TEXT ( FM_SHORT_NAME ( FM_KSL ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_KSL ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_KSL ) ) ;
}
if ( ins - > type = = DIV_INS_OPZ ) {
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( FM_SHORT_NAME ( FM_EGSHIFT ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_EGSHIFT ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_EGSHIFT ) ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( FM_SHORT_NAME ( FM_REV ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_REV ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_REV ) ) ;
}
if ( ins - > type = = DIV_INS_ESFM ) {
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( ESFM_SHORT_NAME ( ESFM_OUTLVL ) ) ;
ImGui : : TextUnformatted ( ESFM_SHORT_NAME ( ESFM_OUTLVL ) ) ;
TOOLTIP_TEXT ( ESFM_LONG_NAME ( ESFM_OUTLVL ) ) ;
}
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( FM_SHORT_NAME ( FM_MULT ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_MULT ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_MULT ) ) ;
if ( ins - > type = = DIV_INS_OPZ ) {
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( FM_SHORT_NAME ( FM_FINE ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_FINE ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_FINE ) ) ;
}
if ( ins - > type = = DIV_INS_ESFM ) {
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( ESFM_SHORT_NAME ( ESFM_CT ) ) ;
ImGui : : TextUnformatted ( ESFM_SHORT_NAME ( ESFM_CT ) ) ;
TOOLTIP_TEXT ( ESFM_LONG_NAME ( ESFM_CT ) ) ;
}
ImGui : : TableNextColumn ( ) ;
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) {
CENTER_TEXT ( FM_SHORT_NAME ( FM_DT ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_DT ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_DT ) ) ;
ImGui : : TableNextColumn ( ) ;
}
if ( ins - > type = = DIV_INS_ESFM ) {
CENTER_TEXT ( ESFM_SHORT_NAME ( ESFM_DT ) ) ;
ImGui : : TextUnformatted ( ESFM_SHORT_NAME ( ESFM_DT ) ) ;
TOOLTIP_TEXT ( ESFM_LONG_NAME ( ESFM_DT ) ) ;
ImGui : : TableNextColumn ( ) ;
}
if ( ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) {
CENTER_TEXT ( FM_SHORT_NAME ( FM_DT2 ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_DT2 ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_DT2 ) ) ;
ImGui : : TableNextColumn ( ) ;
}
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPM ) {
CENTER_TEXT ( FM_SHORT_NAME ( FM_AM ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_AM ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_AM ) ) ;
} else {
CENTER_TEXT ( " Other " ) ;
ImGui : : TextUnformatted ( " Other " ) ;
}
ImGui : : TableNextColumn ( ) ;
if ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_ESFM ) {
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( FM_NAME ( FM_WS ) ) ;
ImGui : : TextUnformatted ( FM_NAME ( FM_WS ) ) ;
} else if ( ins - > type ! = DIV_INS_OPLL & & ins - > type ! = DIV_INS_OPM ) {
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( FM_NAME ( FM_SSG ) ) ;
ImGui : : TextUnformatted ( FM_NAME ( FM_SSG ) ) ;
}
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( _ ( " Envelope " ) ) ;
ImGui : : TextUnformatted ( _ ( " Envelope " ) ) ;
}
2024-05-04 22:10:31 -05:00
void FurnaceGUI : : insTabFM ( DivInstrument * ins ) {
int opCount = 4 ;
if ( ins - > type = = DIV_INS_OPLL ) opCount = 2 ;
if ( ins - > type = = DIV_INS_OPL ) opCount = ( ins - > fm . ops = = 4 ) ? 4 : 2 ;
bool opsAreMutable = ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPM ) ;
if ( ImGui : : BeginTabItem ( " FM " ) ) {
DivInstrumentFM & fmOrigin = ( ins - > type = = DIV_INS_OPLL & & ins - > fm . opllPreset > 0 & & ins - > fm . opllPreset < 16 ) ? opllPreview : ins - > fm ;
bool isPresent [ 4 ] ;
int isPresentCount = 0 ;
memset ( isPresent , 0 , 4 * sizeof ( bool ) ) ;
for ( int i = 0 ; i < e - > song . systemLen ; i + + ) {
if ( e - > song . system [ i ] = = DIV_SYSTEM_VRC7 ) {
isPresent [ 3 ] = true ;
} else if ( e - > song . system [ i ] = = DIV_SYSTEM_OPLL | | e - > song . system [ i ] = = DIV_SYSTEM_OPLL_DRUMS ) {
isPresent [ ( e - > song . systemFlags [ i ] . getInt ( " patchSet " , 0 ) ) & 3 ] = true ;
}
}
if ( ! isPresent [ 0 ] & & ! isPresent [ 1 ] & & ! isPresent [ 2 ] & & ! isPresent [ 3 ] ) {
isPresent [ 0 ] = true ;
}
for ( int i = 0 ; i < 4 ; i + + ) {
if ( isPresent [ i ] ) isPresentCount + + ;
}
int presentWhich = 0 ;
for ( int i = 0 ; i < 4 ; i + + ) {
if ( isPresent [ i ] ) {
presentWhich = i ;
break ;
}
}
2022-10-03 19:08:32 -05:00
2024-05-04 22:10:31 -05:00
if ( ImGui : : BeginTable ( " fmDetails " , 3 , ( ins - > type = = DIV_INS_ESFM ) ? ImGuiTableFlags_SizingStretchProp : ImGuiTableFlags_SizingStretchSame ) ) {
2025-01-28 04:04:01 -05:00
String blockTxt = _ ( " Automatic " ) ;
2024-09-18 14:48:10 +07:00
if ( ins - > fm . block > = 1 ) {
blockTxt = fmt : : sprintf ( " %d " , ins - > fm . block - 1 ) ;
}
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthStretch , ( ( ins - > type = = DIV_INS_ESFM ) ? 0.40f : 0.0f ) ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch , ( ( ins - > type = = DIV_INS_ESFM ) ? 0.25f : 0.0f ) ) ;
2024-05-04 22:10:31 -05:00
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthStretch , ( ( ins - > type = = DIV_INS_ESFM ) ? 0.35f : 0.0f ) ) ;
ImGui : : TableNextRow ( ) ;
switch ( ins - > type ) {
case DIV_INS_FM :
case DIV_INS_OPM :
ImGui : : TableNextColumn ( ) ;
P ( CWSliderScalar ( FM_NAME ( FM_FB ) , ImGuiDataType_U8 , & ins - > fm . fb , & _ZERO , & _SEVEN ) ) ; rightClickable
P ( CWSliderScalar ( FM_NAME ( FM_FMS ) , ImGuiDataType_U8 , & ins - > fm . fms , & _ZERO , & _SEVEN ) ) ; rightClickable
2024-09-18 14:48:10 +07:00
if ( ins - > type = = DIV_INS_FM ) {
P ( CWSliderScalar ( FM_NAME ( FM_BLOCK ) , ImGuiDataType_U8 , & ins - > fm . block , & _ZERO , & _EIGHT , blockTxt . c_str ( ) ) ) ; rightClickable
}
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
P ( CWSliderScalar ( FM_NAME ( FM_ALG ) , ImGuiDataType_U8 , & ins - > fm . alg , & _ZERO , & _SEVEN ) ) ; rightClickable
P ( CWSliderScalar ( FM_NAME ( FM_AMS ) , ImGuiDataType_U8 , & ins - > fm . ams , & _ZERO , & _THREE ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
if ( fmPreviewOn ) {
drawFMPreview ( ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , 48.0 * dpiScale ) ) ;
if ( ! fmPreviewPaused ) {
renderFMPreview ( ins , 1 ) ;
WAKE_UP ;
}
} else {
drawAlgorithm ( ins - > fm . alg , FM_ALGS_4OP , ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , 48.0 * dpiScale ) ) ;
}
kvsConfig ( ins ) ;
break ;
case DIV_INS_OPZ :
ImGui : : TableNextColumn ( ) ;
P ( CWSliderScalar ( FM_NAME ( FM_FB ) , ImGuiDataType_U8 , & ins - > fm . fb , & _ZERO , & _SEVEN ) ) ; rightClickable
P ( CWSliderScalar ( FM_NAME ( FM_FMS ) , ImGuiDataType_U8 , & ins - > fm . fms , & _ZERO , & _SEVEN ) ) ; rightClickable
P ( CWSliderScalar ( FM_NAME ( FM_FMS2 ) , ImGuiDataType_U8 , & ins - > fm . fms2 , & _ZERO , & _SEVEN ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
P ( CWSliderScalar ( FM_NAME ( FM_ALG ) , ImGuiDataType_U8 , & ins - > fm . alg , & _ZERO , & _SEVEN ) ) ; rightClickable
P ( CWSliderScalar ( FM_NAME ( FM_AMS ) , ImGuiDataType_U8 , & ins - > fm . ams , & _ZERO , & _THREE ) ) ; rightClickable
P ( CWSliderScalar ( FM_NAME ( FM_AMS2 ) , ImGuiDataType_U8 , & ins - > fm . ams2 , & _ZERO , & _THREE ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
if ( fmPreviewOn ) {
drawFMPreview ( ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , 48.0 * dpiScale ) ) ;
if ( ! fmPreviewPaused ) {
renderFMPreview ( ins , 1 ) ;
WAKE_UP ;
}
} else {
drawAlgorithm ( ins - > fm . alg , FM_ALGS_4OP , ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , 48.0 * dpiScale ) ) ;
}
kvsConfig ( ins ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Button ( _ ( " Request from TX81Z " ) ) ) {
2024-05-04 22:10:31 -05:00
doAction ( GUI_ACTION_TX81Z_REQUEST ) ;
}
/*
ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( " Send to TX81Z " ) ) {
showError ( " Coming soon! " ) ;
}
*/
break ;
case DIV_INS_OPL :
case DIV_INS_OPL_DRUMS : {
bool fourOp = ( ins - > fm . ops = = 4 | | ins - > type = = DIV_INS_OPL_DRUMS ) ;
bool drums = ins - > fm . opllPreset = = 16 ;
int algMax = fourOp ? 3 : 1 ;
ImGui : : TableNextColumn ( ) ;
ins - > fm . alg & = algMax ;
P ( CWSliderScalar ( FM_NAME ( FM_FB ) , ImGuiDataType_U8 , & ins - > fm . fb , & _ZERO , & _SEVEN ) ) ; rightClickable
2025-01-28 04:04:01 -05:00
P ( CWSliderScalar ( FM_NAME ( FM_BLOCK ) , ImGuiDataType_U8 , & ins - > fm . block , & _ZERO , & _EIGHT , blockTxt . c_str ( ) ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
P ( CWSliderScalar ( FM_NAME ( FM_ALG ) , ImGuiDataType_U8 , & ins - > fm . alg , & _ZERO , & algMax ) ) ; rightClickable
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_OPL ) {
ImGui : : BeginDisabled ( ins - > fm . opllPreset = = 16 ) ;
if ( ImGui : : Checkbox ( " 4-op " , & fourOp ) ) { PARAMETER
ins - > fm . ops = fourOp ? 4 : 2 ;
}
ImGui : : EndDisabled ( ) ;
2025-01-28 04:04:01 -05:00
ImGui : : SameLine ( ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Checkbox ( _ ( " Drums " ) , & drums ) ) { PARAMETER
2024-05-04 22:10:31 -05:00
ins - > fm . opllPreset = drums ? 16 : 0 ;
}
}
ImGui : : TableNextColumn ( ) ;
if ( fmPreviewOn ) {
drawFMPreview ( ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , 48.0 * dpiScale ) ) ;
if ( ! fmPreviewPaused ) {
renderFMPreview ( ins , 1 ) ;
WAKE_UP ;
}
} else {
drawAlgorithm ( ins - > fm . alg & algMax , fourOp ? FM_ALGS_4OP_OPL : FM_ALGS_2OP_OPL , ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , 48.0 * dpiScale ) ) ;
}
kvsConfig ( ins ) ;
break ;
}
case DIV_INS_OPLL : {
bool dc = fmOrigin . fms ;
bool dm = fmOrigin . ams ;
bool sus = ins - > fm . alg ;
ImGui : : TableNextColumn ( ) ;
ImGui : : BeginDisabled ( ins - > fm . opllPreset ! = 0 ) ;
P ( CWSliderScalar ( FM_NAME ( FM_FB ) , ImGuiDataType_U8 , & fmOrigin . fb , & _ZERO , & _SEVEN ) ) ; rightClickable
ImGui : : EndDisabled ( ) ;
2025-01-28 04:04:01 -05:00
P ( CWSliderScalar ( FM_NAME ( FM_BLOCK ) , ImGuiDataType_U8 , & ins - > fm . block , & _ZERO , & _EIGHT , blockTxt . c_str ( ) ) ) ; rightClickable
2024-09-18 14:48:10 +07:00
if ( ins - > fm . opllPreset ! = 0 ) {
ins - > fm . op [ 1 ] . tl & = 15 ;
P ( CWSliderScalar ( _ ( " Volume##TL " ) , ImGuiDataType_U8 , & ins - > fm . op [ 1 ] . tl , & _FIFTEEN , & _ZERO ) ) ; rightClickable
}
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : Checkbox ( FM_NAME ( FM_SUS ) , & sus ) ) { PARAMETER
ins - > fm . alg = sus ;
}
ImGui : : BeginDisabled ( ins - > fm . opllPreset ! = 0 ) ;
2025-01-28 04:04:01 -05:00
if ( ImGui : : Checkbox ( FM_NAME ( FM_DC ) , & dc ) ) { PARAMETER
fmOrigin . fms = dc ;
}
ImGui : : SameLine ( ) ;
2024-05-04 22:10:31 -05:00
if ( ImGui : : Checkbox ( FM_NAME ( FM_DM ) , & dm ) ) { PARAMETER
fmOrigin . ams = dm ;
}
ImGui : : EndDisabled ( ) ;
ImGui : : TableNextColumn ( ) ;
if ( fmPreviewOn ) {
drawFMPreview ( ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , 24.0 * dpiScale ) ) ;
if ( ! fmPreviewPaused ) {
renderFMPreview ( ins , 1 ) ;
WAKE_UP ;
}
} else {
drawAlgorithm ( 0 , FM_ALGS_2OP_OPL , ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , 24.0 * dpiScale ) ) ;
}
kvsConfig ( ins , false ) ;
2022-10-03 19:08:32 -05:00
2023-08-15 11:58:05 -07:00
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
2024-05-04 22:10:31 -05:00
2024-05-26 19:31:17 -05:00
if ( ImGui : : BeginCombo ( " ##LLPreset " , _ ( opllInsNames [ presentWhich ] [ ins - > fm . opllPreset ] ) ) ) {
2024-05-04 22:10:31 -05:00
if ( isPresentCount > 1 ) {
if ( ImGui : : BeginTable ( " LLPresetList " , isPresentCount ) ) {
ImGui : : TableNextRow ( ImGuiTableRowFlags_Headers ) ;
for ( int i = 0 ; i < 4 ; i + + ) {
if ( ! isPresent [ i ] ) continue ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " %s name " ) , opllVariants [ i ] ) ;
2024-05-04 22:10:31 -05:00
}
for ( int i = 0 ; i < 17 ; i + + ) {
ImGui : : TableNextRow ( ) ;
for ( int j = 0 ; j < 4 ; j + + ) {
if ( ! isPresent [ j ] ) continue ;
ImGui : : TableNextColumn ( ) ;
ImGui : : PushID ( j * 17 + i ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Selectable ( _ ( opllInsNames [ j ] [ i ] ) ) ) {
2024-05-04 22:10:31 -05:00
ins - > fm . opllPreset = i ;
}
ImGui : : PopID ( ) ;
}
}
ImGui : : EndTable ( ) ;
}
} else {
for ( int i = 0 ; i < 17 ; i + + ) {
2024-05-26 19:31:17 -05:00
if ( ImGui : : Selectable ( _ ( opllInsNames [ presentWhich ] [ i ] ) ) ) {
2024-05-04 22:10:31 -05:00
ins - > fm . opllPreset = i ;
}
2022-10-03 19:08:32 -05:00
}
}
ImGui : : EndCombo ( ) ;
}
2024-05-04 22:10:31 -05:00
break ;
2022-10-08 17:57:14 -05:00
}
2024-05-04 22:10:31 -05:00
case DIV_INS_ESFM : {
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
P ( CWSliderScalar ( ESFM_LONG_NAME ( ESFM_NOISE ) , ImGuiDataType_U8 , & ins - > esfm . noise , & _ZERO , & _THREE , _ ( esfmNoiseModeNames [ ins - > esfm . noise & 3 ] ) ) ) ; rightClickable
ImGui : : TextUnformatted ( _ ( esfmNoiseModeDescriptions [ ins - > esfm . noise & 3 ] ) ) ;
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
2024-09-18 14:48:10 +07:00
P ( CWSliderScalar ( FM_NAME ( FM_BLOCK ) , ImGuiDataType_U8 , & ins - > fm . block , & _ZERO , & _EIGHT , blockTxt . c_str ( ) ) ) ; rightClickable
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
if ( fmPreviewOn ) {
drawFMPreview ( ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , 48.0 * dpiScale ) ) ;
if ( ! fmPreviewPaused ) {
renderFMPreview ( ins , 1 ) ;
WAKE_UP ;
}
} else {
drawESFMAlgorithm ( ins - > esfm , ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , 48.0 * dpiScale ) ) ;
}
kvsConfig ( ins ) ;
2022-10-03 19:08:32 -05:00
}
2024-05-04 22:10:31 -05:00
default :
break ;
}
ImGui : : EndTable ( ) ;
}
2024-09-18 14:48:10 +07:00
if ( ins - > type = = DIV_INS_OPLL & & ins - > fm . opllPreset = = 16 ) {
ImGui : : Text ( _ ( " this volume slider only works in compatibility (non-drums) system. " ) ) ;
}
2022-10-03 19:08:32 -05:00
2024-05-04 22:10:31 -05:00
if ( ( ( ins - > type = = DIV_INS_OPLL | | ins - > type = = DIV_INS_OPL ) & & ins - > fm . opllPreset = = 16 ) | | ins - > type = = DIV_INS_OPL_DRUMS ) {
ins - > fm . ops = 2 ;
2024-05-26 19:31:17 -05:00
P ( ImGui : : Checkbox ( _ ( " Fixed frequency mode " ) , & ins - > fm . fixedDrums ) ) ;
2024-05-04 22:10:31 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " when enabled, drums will be set to the specified frequencies, ignoring the note. " ) ) ;
2022-10-03 19:08:32 -05:00
}
2024-05-04 22:10:31 -05:00
if ( ins - > fm . fixedDrums ) {
int block = 0 ;
int fNum = 0 ;
if ( ImGui : : BeginTable ( " fixedDrumSettings " , 3 ) ) {
ImGui : : TableNextRow ( ImGuiTableRowFlags_Headers ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Drum " ) ) ;
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Block " ) ) ;
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " FreqNum " ) ) ;
2024-05-04 22:10:31 -05:00
2024-05-26 19:31:17 -05:00
DRUM_FREQ ( _ ( " Kick " ) , " ##DBlock0 " , " ##DFreq0 " , ins - > fm . kickFreq ) ;
DRUM_FREQ ( _ ( " Snare/Hi-hat " ) , " ##DBlock1 " , " ##DFreq1 " , ins - > fm . snareHatFreq ) ;
DRUM_FREQ ( _ ( " Tom/Top " ) , " ##DBlock2 " , " ##DFreq2 " , ins - > fm . tomTopFreq ) ;
2024-05-04 22:10:31 -05:00
ImGui : : EndTable ( ) ;
}
2023-03-18 04:22:50 -05:00
}
2024-05-04 22:10:31 -05:00
}
bool willDisplayOps = true ;
if ( ins - > type = = DIV_INS_OPLL & & ins - > fm . opllPreset ! = 0 ) willDisplayOps = false ;
if ( ! willDisplayOps & & ins - > type = = DIV_INS_OPLL ) {
// update OPLL preset preview
if ( ins - > fm . opllPreset > 0 & & ins - > fm . opllPreset < 16 ) {
const opll_patch_t * patchROM = NULL ;
switch ( presentWhich ) {
case 1 :
patchROM = OPLL_GetPatchROM ( opll_type_ymf281 ) ;
break ;
case 2 :
patchROM = OPLL_GetPatchROM ( opll_type_ym2423 ) ;
break ;
case 3 :
patchROM = OPLL_GetPatchROM ( opll_type_ds1001 ) ;
break ;
default :
patchROM = OPLL_GetPatchROM ( opll_type_ym2413 ) ;
break ;
}
const opll_patch_t * patch = & patchROM [ ins - > fm . opllPreset - 1 ] ;
opllPreview . alg = ins - > fm . alg ;
opllPreview . fb = patch - > fb ;
2024-09-10 18:10:42 +02:00
opllPreview . fms = patch - > dc ;
opllPreview . ams = patch - > dm ;
2024-05-04 22:10:31 -05:00
opllPreview . op [ 0 ] . tl = patch - > tl ;
opllPreview . op [ 1 ] . tl = ins - > fm . op [ 1 ] . tl ;
for ( int i = 0 ; i < 2 ; i + + ) {
opllPreview . op [ i ] . am = patch - > am [ i ] ;
opllPreview . op [ i ] . vib = patch - > vib [ i ] ;
opllPreview . op [ i ] . ssgEnv = patch - > et [ i ] ? 8 : 0 ;
opllPreview . op [ i ] . ksr = patch - > ksr [ i ] ;
2024-09-10 18:10:42 +02:00
opllPreview . op [ i ] . ksl = patch - > ksl [ i ] ;
2024-05-04 22:10:31 -05:00
opllPreview . op [ i ] . mult = patch - > multi [ i ] ;
opllPreview . op [ i ] . ar = patch - > ar [ i ] ;
opllPreview . op [ i ] . dr = patch - > dr [ i ] ;
opllPreview . op [ i ] . sl = patch - > sl [ i ] ;
opllPreview . op [ i ] . rr = patch - > rr [ i ] ;
2023-12-18 11:01:11 -05:00
}
2022-04-12 21:30:12 -05:00
}
2024-05-04 22:10:31 -05:00
}
ImGui : : BeginDisabled ( ! willDisplayOps ) ;
2024-07-25 19:59:21 -05:00
if ( settings . fmLayout = = 0 | | settings . fmLayout = = 7 ) {
2024-05-04 22:10:31 -05:00
int numCols = 15 ;
if ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS ) numCols = 13 ;
if ( ins - > type = = DIV_INS_OPLL ) numCols = 12 ;
if ( ins - > type = = DIV_INS_OPZ ) numCols = 19 ;
if ( ins - > type = = DIV_INS_ESFM ) numCols = 19 ;
if ( ImGui : : BeginTable ( " FMOperators " , numCols , ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersOuterV ) ) {
// configure columns
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthFixed ) ; // op name
if ( ins - > type = = DIV_INS_ESFM ) {
ImGui : : TableSetupColumn ( " c0e0 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // outLvl
ImGui : : TableSetupColumn ( " c0e1 " , ImGuiTableColumnFlags_WidthFixed ) ; // -separator-
ImGui : : TableSetupColumn ( " c0e2 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // delay
}
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // ar
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // dr
2025-03-14 13:55:43 -05:00
if ( settings . susPosition = = 0 ) {
ImGui : : TableSetupColumn ( " c3 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // sl
}
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) {
ImGui : : TableSetupColumn ( " c4 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // d2r
}
ImGui : : TableSetupColumn ( " c5 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // rr
2025-03-14 13:55:43 -05:00
if ( settings . susPosition = = 1 ) {
ImGui : : TableSetupColumn ( " c3 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // sl
}
2024-05-04 22:10:31 -05:00
ImGui : : TableSetupColumn ( " c6 " , ImGuiTableColumnFlags_WidthFixed ) ; // -separator-
2025-03-14 13:55:43 -05:00
if ( settings . susPosition = = 2 ) {
ImGui : : TableSetupColumn ( " c3 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // sl
}
2024-05-04 22:10:31 -05:00
ImGui : : TableSetupColumn ( " c7 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // tl
2025-03-14 13:55:43 -05:00
if ( settings . susPosition = = 3 ) {
ImGui : : TableSetupColumn ( " c3 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // sl
}
2024-05-04 22:10:31 -05:00
ImGui : : TableSetupColumn ( " c8 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // rs/ksl
if ( ins - > type = = DIV_INS_OPZ ) {
ImGui : : TableSetupColumn ( " c8z0 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // egs
ImGui : : TableSetupColumn ( " c8z1 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // rev
}
if ( ins - > type = = DIV_INS_ESFM ) {
ImGui : : TableSetupColumn ( " c8e0 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // outLvl
2022-04-02 18:22:06 -05:00
}
2024-05-04 22:10:31 -05:00
ImGui : : TableSetupColumn ( " c9 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // mult
2022-04-02 18:22:06 -05:00
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_OPZ ) {
ImGui : : TableSetupColumn ( " c9z " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // fine
}
2022-04-02 18:22:06 -05:00
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_ESFM ) {
ImGui : : TableSetupColumn ( " c9e " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // ct
2022-04-02 18:22:06 -05:00
}
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM | | ins - > type = = DIV_INS_ESFM ) {
ImGui : : TableSetupColumn ( " c10 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // dt
}
if ( ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) {
ImGui : : TableSetupColumn ( " c11 " , ImGuiTableColumnFlags_WidthStretch , 0.05f ) ; // dt2
}
ImGui : : TableSetupColumn ( " c15 " , ImGuiTableColumnFlags_WidthFixed ) ; // am
ImGui : : TableSetupColumn ( " c12 " , ImGuiTableColumnFlags_WidthFixed ) ; // -separator-
if ( ins - > type ! = DIV_INS_OPLL & & ins - > type ! = DIV_INS_OPM ) {
ImGui : : TableSetupColumn ( " c13 " , ImGuiTableColumnFlags_WidthStretch , 0.2f ) ; // ssg/waveform
}
ImGui : : TableSetupColumn ( " c14 " , ImGuiTableColumnFlags_WidthStretch , 0.3f ) ; // env
2024-07-25 19:59:21 -05:00
float sliderHeight = ( ( ImGui : : GetContentRegionAvail ( ) . y - ImGui : : GetFrameHeightWithSpacing ( ) * ( settings . fmLayout = = 7 ? 4.0f : 1.0f ) ) / opCount ) - ImGui : : GetStyle ( ) . ItemSpacing . y ;
2024-05-04 22:10:31 -05:00
// header
2024-07-25 19:59:21 -05:00
if ( settings . fmLayout = = 0 ) {
insTabFMModernHeader ( ins ) ;
2022-12-11 04:32:51 +09:00
}
2024-05-04 22:10:31 -05:00
2024-07-25 19:59:21 -05:00
// main view
2024-05-04 22:10:31 -05:00
for ( int i = 0 ; i < opCount ; i + + ) {
DivInstrumentFM : : Operator & op = fmOrigin . op [ ( opCount = = 4 & & ins - > type ! = DIV_INS_OPL_DRUMS & & ins - > type ! = DIV_INS_ESFM ) ? opOrder [ i ] : i ] ;
DivInstrumentESFM : : Operator & opE = ins - > esfm . op [ i ] ;
2024-07-25 19:59:21 -05:00
// modern with more labels
if ( settings . fmLayout = = 7 ) {
insTabFMModernHeader ( ins ) ;
}
2024-05-04 22:10:31 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
// push colors
if ( settings . separateFMColors ) {
bool mod = true ;
if ( ins - > type = = DIV_INS_OPL_DRUMS ) {
mod = false ;
} else if ( ins - > type = = DIV_INS_ESFM ) {
// this is the same as the KVS heuristic in platform/esfm.h
if ( opE . outLvl = = 7 ) {
mod = false ;
} else if ( opE . outLvl > 0 ) {
if ( i = = 3 ) {
mod = false ;
} else {
DivInstrumentESFM : : Operator & opENext = ins - > esfm . op [ i + 1 ] ;
if ( opENext . modIn = = 0 ) {
mod = false ;
} else if ( ( opE . outLvl - opENext . modIn ) > = 2 ) {
mod = false ;
}
}
}
} else if ( opCount = = 4 ) {
if ( ins - > type = = DIV_INS_OPL ) {
if ( opIsOutputOPL [ fmOrigin . alg & 3 ] [ i ] ) mod = false ;
} else {
if ( opIsOutput [ fmOrigin . alg & 7 ] [ i ] ) mod = false ;
}
} else {
if ( i = = 1 | | ( ins - > type = = DIV_INS_OPL & & ( fmOrigin . alg & 1 ) ) ) mod = false ;
}
if ( mod ) {
pushAccentColors (
uiColors [ GUI_COLOR_FM_PRIMARY_MOD ] ,
uiColors [ GUI_COLOR_FM_SECONDARY_MOD ] ,
uiColors [ GUI_COLOR_FM_BORDER_MOD ] ,
uiColors [ GUI_COLOR_FM_BORDER_SHADOW_MOD ]
) ;
} else {
pushAccentColors (
uiColors [ GUI_COLOR_FM_PRIMARY_CAR ] ,
uiColors [ GUI_COLOR_FM_SECONDARY_CAR ] ,
uiColors [ GUI_COLOR_FM_BORDER_CAR ] ,
uiColors [ GUI_COLOR_FM_BORDER_SHADOW_CAR ]
) ;
2022-05-20 02:43:39 -05:00
}
}
2022-05-08 04:45:48 -05:00
2024-05-04 22:10:31 -05:00
if ( i = = 0 ) {
float sliderMinHeightOPL = ImGui : : GetFrameHeight ( ) * 4.0 + ImGui : : GetStyle ( ) . ItemSpacing . y * 3.0 ;
float sliderMinHeightESFM = ImGui : : GetFrameHeight ( ) * 5.0 + ImGui : : GetStyle ( ) . ItemSpacing . y * 4.0 ;
if ( ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS | | ins - > type = = DIV_INS_OPLL ) & & sliderHeight < sliderMinHeightOPL ) {
sliderHeight = sliderMinHeightOPL ;
}
if ( ins - > type = = DIV_INS_ESFM & & sliderHeight < sliderMinHeightESFM ) {
sliderHeight = sliderMinHeightESFM ;
2022-04-27 04:48:56 -05:00
}
}
2024-05-04 22:10:31 -05:00
ImGui : : PushID ( fmt : : sprintf ( " op%d " , i ) . c_str ( ) ) ;
String opNameLabel ;
if ( ins - > type = = DIV_INS_OPL_DRUMS ) {
opNameLabel = fmt : : sprintf ( " %s " , oplDrumNames [ i ] ) ;
} else if ( ins - > type = = DIV_INS_OPL & & fmOrigin . opllPreset = = 16 ) {
if ( i = = 1 ) {
2024-05-26 19:31:17 -05:00
opNameLabel = _ ( " Kick " ) ;
2024-05-04 22:10:31 -05:00
} else {
2024-05-26 19:31:17 -05:00
opNameLabel = _ ( " Env " ) ;
2024-05-04 22:10:31 -05:00
}
} else {
opNameLabel = fmt : : sprintf ( " OP%d " , i + 1 ) ;
}
if ( opsAreMutable ) {
pushToggleColors ( op . enable ) ;
if ( ImGui : : Button ( opNameLabel . c_str ( ) ) ) {
op . enable = ! op . enable ;
PARAMETER ;
}
popToggleColors ( ) ;
} else {
ImGui : : TextUnformatted ( opNameLabel . c_str ( ) ) ;
2023-10-15 17:02:25 -05:00
}
2022-04-02 18:22:06 -05:00
2024-05-04 22:10:31 -05:00
// drag point
OP_DRAG_POINT ;
2022-02-17 13:08:17 -05:00
2024-05-04 22:10:31 -05:00
int maxTl = 127 ;
if ( ins - > type = = DIV_INS_OPLL ) {
if ( i = = 1 ) {
maxTl = 15 ;
} else {
maxTl = 63 ;
2023-07-09 05:35:49 -05:00
}
2024-05-04 22:10:31 -05:00
}
if ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS | | ins - > type = = DIV_INS_ESFM ) {
maxTl = 63 ;
}
int maxArDr = ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) ? 31 : 15 ;
bool ssgOn = op . ssgEnv & 8 ;
bool ksrOn = op . ksr ;
bool vibOn = op . vib ;
bool susOn = op . sus ;
bool fixedOn = opE . fixed ;
unsigned char ssgEnv = op . ssgEnv & 7 ;
if ( ins - > type = = DIV_INS_ESFM ) {
ImGui : : TableNextColumn ( ) ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##MODIN " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & opE . modIn , & _ZERO , & _SEVEN ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Dummy ( ImVec2 ( 4.0f * dpiScale , 2.0f * dpiScale ) ) ;
ImGui : : TableNextColumn ( ) ;
opE . delay & = 7 ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##DELAY " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & opE . delay , & _ZERO , & _SEVEN ) ) ; rightClickable
}
ImGui : : TableNextColumn ( ) ;
op . ar & = maxArDr ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##AR " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . ar , & maxArDr , & _ZERO ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
op . dr & = maxArDr ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##DR " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . dr , & maxArDr , & _ZERO ) ) ; rightClickable
if ( settings . susPosition = = 0 ) {
ImGui : : TableNextColumn ( ) ;
op . sl & = 15 ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##SL " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . sl , & _FIFTEEN , & _ZERO ) ) ; rightClickable
}
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) {
ImGui : : TableNextColumn ( ) ;
op . d2r & = 31 ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##D2R " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . d2r , & _THIRTY_ONE , & _ZERO ) ) ; rightClickable
}
ImGui : : TableNextColumn ( ) ;
op . rr & = 15 ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##RR " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . rr , & _FIFTEEN , & _ZERO ) ) ; rightClickable
2024-07-25 20:03:10 -05:00
if ( settings . susPosition = = 1 ) {
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
op . sl & = 15 ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##SL " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . sl , & _FIFTEEN , & _ZERO ) ) ; rightClickable
}
ImGui : : TableNextColumn ( ) ;
ImGui : : Dummy ( ImVec2 ( 4.0f * dpiScale , 2.0f * dpiScale ) ) ;
2024-07-25 20:03:10 -05:00
if ( settings . susPosition = = 2 ) {
ImGui : : TableNextColumn ( ) ;
op . sl & = 15 ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##SL " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . sl , & _FIFTEEN , & _ZERO ) ) ; rightClickable
}
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
op . tl & = maxTl ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##TL " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . tl , & maxTl , & _ZERO ) ) ; rightClickable
2024-07-25 20:03:10 -05:00
if ( settings . susPosition = = 3 ) {
ImGui : : TableNextColumn ( ) ;
op . sl & = 15 ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##SL " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . sl , & _FIFTEEN , & _ZERO ) ) ; rightClickable
}
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
CENTER_VSLIDER ;
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) {
P ( CWVSliderScalar ( " ##RS " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . rs , & _ZERO , & _THREE ) ) ; rightClickable
} else {
int ksl = ins - > type = = DIV_INS_OPLL ? op . ksl : kslMap [ op . ksl & 3 ] ;
if ( CWVSliderInt ( " ##KSL " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , & ksl , 0 , 3 ) ) {
op . ksl = ( ins - > type = = DIV_INS_OPLL ? ksl : kslMap [ ksl & 3 ] ) ;
PARAMETER ;
} rightClickable
}
if ( ins - > type = = DIV_INS_OPZ ) {
ImGui : : TableNextColumn ( ) ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##EGS " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . ksl , & _ZERO , & _THREE ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##REV " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . dam , & _ZERO , & _SEVEN ) ) ; rightClickable
}
if ( ins - > type = = DIV_INS_ESFM ) {
ImGui : : TableNextColumn ( ) ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##OUTLVL " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & opE . outLvl , & _ZERO , & _SEVEN ) ) ; rightClickable
}
ImGui : : TableNextColumn ( ) ;
2024-11-11 03:57:23 -05:00
pushWarningColor ( ins - > type = = DIV_INS_OPL_DRUMS & & i = = 0 ) ;
2024-05-04 22:10:31 -05:00
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##MULT " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . mult , & _ZERO , & _FIFTEEN ) ) ; rightClickable
2024-11-11 03:57:23 -05:00
if ( ins - > type = = DIV_INS_OPL_DRUMS & & i = = 0 ) {
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( " %s " , _ ( " Snare's multiplier is determined by HiHat's. " ) ) ;
}
}
popWarningColor ( ) ;
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_OPZ ) {
ImGui : : TableNextColumn ( ) ;
CENTER_VSLIDER ;
2024-08-25 13:33:01 +03:00
bool egtOn = op . egt ;
2024-09-22 03:58:17 -05:00
if ( ! egtOn ) {
2024-08-25 13:33:01 +03:00
P ( CWVSliderScalar ( " ##FINE " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . dvb , & _ZERO , & _FIFTEEN ) ) ; rightClickable
}
2024-05-04 22:10:31 -05:00
}
if ( ins - > type = = DIV_INS_ESFM ) {
ImGui : : TableNextColumn ( ) ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##CT " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_S8 , & opE . ct , & _MINUS_TWENTY_FOUR , & _TWENTY_FOUR ) ) ; rightClickable
}
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) {
int detune = detuneMap [ settings . unsignedDetune ? 1 : 0 ] [ op . dt & 7 ] ;
ImGui : : TableNextColumn ( ) ;
CENTER_VSLIDER ;
if ( CWVSliderInt ( " ##DT " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , & detune , settings . unsignedDetune ? 0 : - 3 , settings . unsignedDetune ? 7 : 4 ) ) { PARAMETER
if ( detune < - 3 ) detune = - 3 ;
if ( detune > 7 ) detune = 7 ;
op . dt = detuneUnmap [ settings . unsignedDetune ? 1 : 0 ] [ detune + 3 ] ;
} rightClickable
if ( ins - > type ! = DIV_INS_FM ) {
ImGui : : TableNextColumn ( ) ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##DT2 " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . dt2 , & _ZERO , & _THREE ) ) ; rightClickable
2023-07-09 05:35:49 -05:00
}
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
bool amOn = op . am ;
if ( ins - > type = = DIV_INS_OPZ ) {
bool egtOn = op . egt ;
2024-08-25 17:26:59 +03:00
bool susOn = op . sus ;
2024-05-04 22:10:31 -05:00
if ( egtOn ) {
2024-08-25 17:26:59 +03:00
ImGui : : SetCursorPosY ( ImGui : : GetCursorPosY ( ) + 0.5 * ( sliderHeight - ImGui : : GetFrameHeight ( ) * 4.0 - ImGui : : GetStyle ( ) . ItemSpacing . y * 3.5 ) ) ;
2024-05-04 22:10:31 -05:00
} else {
ImGui : : SetCursorPosY ( ImGui : : GetCursorPosY ( ) + 0.5 * ( sliderHeight - ImGui : : GetFrameHeight ( ) * 2.0 - ImGui : : GetStyle ( ) . ItemSpacing . y * 1.0 ) ) ;
}
if ( ImGui : : Checkbox ( " AM " , & amOn ) ) { PARAMETER
op . am = amOn ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : Checkbox ( _ ( " Fixed " ) , & egtOn ) ) { PARAMETER
2024-05-04 22:10:31 -05:00
op . egt = egtOn ;
}
if ( egtOn ) {
2025-10-22 14:00:52 -05:00
pushWarningColor ( susOn & & ! e - > song . linearPitch ) ;
2024-09-22 16:56:54 -05:00
if ( ImGui : : Checkbox ( _ ( " Pitch control " ) , & susOn ) ) { PARAMETER
2024-08-25 17:26:59 +03:00
op . sus = susOn ;
// HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly
2025-03-10 12:35:05 -05:00
ins - > temp . vZoom [ DIV_MACRO_OP_SSG + ( i < < 5 ) ] = - 1 ;
ins - > temp . vZoom [ DIV_MACRO_OP_SUS + ( i < < 5 ) ] = - 1 ;
2024-08-25 17:26:59 +03:00
}
2024-09-22 16:56:54 -05:00
popWarningColor ( ) ;
2024-09-22 03:58:17 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2025-10-22 14:00:52 -05:00
if ( susOn & & ! e - > song . linearPitch ) {
2024-09-22 16:56:54 -05:00
ImGui : : SetTooltip ( _ ( " only works on linear pitch! go to Compatibility Flags > Pitch/Playback and set Pitch linearity to Full. " ) ) ;
} else {
ImGui : : SetTooltip ( _ ( " use op's arpeggio and pitch macros control instead of block/f-num macros " ) ) ;
}
2024-08-25 17:26:59 +03:00
}
}
if ( egtOn & & ! susOn ) {
2024-05-04 22:10:31 -05:00
int block = op . dt ;
int freqNum = ( op . mult < < 4 ) | ( op . dvb & 15 ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputInt ( _ ( " Block " ) , & block , 1 , 1 ) ) {
2024-05-04 22:10:31 -05:00
if ( block < 0 ) block = 0 ;
if ( block > 7 ) block = 7 ;
op . dt = block ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputInt ( _ ( " FreqNum " ) , & freqNum , 1 , 16 ) ) {
2024-05-04 22:10:31 -05:00
if ( freqNum < 0 ) freqNum = 0 ;
if ( freqNum > 255 ) freqNum = 255 ;
op . mult = freqNum > > 4 ;
op . dvb = freqNum & 15 ;
}
}
} else {
ImGui : : SetCursorPosY ( ImGui : : GetCursorPosY ( ) + 0.5 * ( sliderHeight - ImGui : : GetFrameHeight ( ) ) ) ;
if ( ImGui : : Checkbox ( " ##AM " , & amOn ) ) { PARAMETER
op . am = amOn ;
}
2023-07-09 05:35:49 -05:00
}
2024-05-04 22:10:31 -05:00
if ( ins - > type ! = DIV_INS_OPL & & ins - > type ! = DIV_INS_OPL_DRUMS & & ins - > type ! = DIV_INS_OPZ & & ins - > type ! = DIV_INS_OPM ) {
ImGui : : TableNextColumn ( ) ;
ImGui : : Dummy ( ImVec2 ( 4.0f * dpiScale , 2.0f * dpiScale ) ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : BeginDisabled ( ! ssgOn ) ;
drawSSGEnv ( op . ssgEnv & 7 , ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , sliderHeight - ImGui : : GetFrameHeightWithSpacing ( ) ) ) ;
ImGui : : EndDisabled ( ) ;
if ( ImGui : : Checkbox ( " ##SSGOn " , & ssgOn ) ) { PARAMETER
op . ssgEnv = ( op . ssgEnv & 7 ) | ( ssgOn < < 3 ) ;
}
ImGui : : SameLine ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
2024-05-26 19:31:17 -05:00
if ( CWSliderScalar ( " ##SSG " , ImGuiDataType_U8 , & ssgEnv , & _ZERO , & _SEVEN , _ ( ssgEnvTypes [ ssgEnv ] ) ) ) { PARAMETER
2024-05-04 22:10:31 -05:00
op . ssgEnv = ( op . ssgEnv & 8 ) | ( ssgEnv & 7 ) ;
2023-07-09 05:35:49 -05:00
}
}
2024-05-04 22:10:31 -05:00
} else if ( ins - > type = = DIV_INS_ESFM ) {
ImGui : : TableNextColumn ( ) ;
CENTER_VSLIDER ;
P ( CWVSliderScalar ( " ##DT " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_S8 , & opE . dt , & _MINUS_ONE_HUNDRED_TWENTY_EIGHT , & _ONE_HUNDRED_TWENTY_SEVEN ) ) ; rightClickable
2023-07-09 05:35:49 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
bool amOn = op . am ;
bool leftOn = opE . left ;
bool rightOn = opE . right ;
ImGui : : SetCursorPosY ( ImGui : : GetCursorPosY ( ) + 0.5 * ( sliderHeight - ImGui : : GetFrameHeight ( ) * 5.0 - ImGui : : GetStyle ( ) . ItemSpacing . y * 4.0 ) ) ;
ImVec2 curPosBeforeDummy = ImGui : : GetCursorPos ( ) ;
ImGui : : Dummy ( ImVec2 ( ImGui : : GetFrameHeightWithSpacing ( ) * 2.0f + ImGui : : CalcTextSize ( FM_SHORT_NAME ( FM_DAM ) ) . x * 2.0f , 1.0f ) ) ;
ImGui : : SetCursorPos ( curPosBeforeDummy ) ;
if ( ImGui : : BeginTable ( " panCheckboxes " , ( fixedOn ) ? 3 : 2 , ImGuiTableFlags_SizingStretchProp ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthStretch , 1.0 ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch , 1.0 ) ;
if ( fixedOn ) {
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthStretch , 1.2 ) ;
}
2023-07-09 05:28:14 -05:00
2024-05-04 22:10:31 -05:00
float yCoordBeforeTablePadding = ImGui : : GetCursorPosY ( ) ;
2023-10-22 11:46:34 -03:00
ImGui : : TableNextRow ( ) ;
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : SetCursorPosY ( yCoordBeforeTablePadding ) ;
if ( ImGui : : Checkbox ( ESFM_SHORT_NAME ( ESFM_LEFT ) , & leftOn ) ) { PARAMETER
opE . left = leftOn ;
}
ImGui : : TableNextColumn ( ) ;
ImGui : : SetCursorPosY ( yCoordBeforeTablePadding ) ;
if ( ImGui : : Checkbox ( ESFM_SHORT_NAME ( ESFM_RIGHT ) , & rightOn ) ) { PARAMETER
opE . right = rightOn ;
}
if ( fixedOn ) {
ImGui : : TableNextColumn ( ) ;
ImGui : : SetCursorPosY ( yCoordBeforeTablePadding ) ;
if ( ImGui : : Checkbox ( FM_SHORT_NAME ( FM_AM ) , & amOn ) ) { PARAMETER
op . am = amOn ;
}
}
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : Checkbox ( FM_SHORT_NAME ( FM_KSR ) , & ksrOn ) ) { PARAMETER
op . ksr = ksrOn ;
}
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : Checkbox ( FM_SHORT_NAME ( FM_SUS ) , & susOn ) ) { PARAMETER
op . sus = susOn ;
}
if ( fixedOn ) {
bool damOn = op . dam ;
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : Checkbox ( FM_SHORT_NAME ( FM_DAM ) , & damOn ) ) { PARAMETER
op . dam = damOn ;
}
}
ImGui : : EndTable ( ) ;
}
ImGui : : SetCursorPosY ( ImGui : : GetCursorPosY ( ) - 0.5 * ImGui : : GetStyle ( ) . ItemSpacing . y ) ;
if ( ImGui : : Checkbox ( ESFM_NAME ( ESFM_FIXED ) , & fixedOn ) ) { PARAMETER
opE . fixed = fixedOn ;
// HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly
2025-03-10 12:35:05 -05:00
ins - > temp . vZoom [ DIV_MACRO_OP_SSG + ( i < < 5 ) ] = - 1 ;
ins - > temp . vZoom [ DIV_MACRO_OP_DT + ( i < < 5 ) ] = - 1 ;
2024-05-04 22:10:31 -05:00
}
if ( ins - > type = = DIV_INS_ESFM ) {
if ( fixedOn ) {
int block = ( opE . ct > > 2 ) & 7 ;
int freqNum = ( ( opE . ct & 3 ) < < 8 ) | ( ( unsigned char ) opE . dt ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputInt ( _ ( " Block " ) , & block , 1 , 1 ) ) {
2024-05-04 22:10:31 -05:00
if ( block < 0 ) block = 0 ;
if ( block > 7 ) block = 7 ;
opE . ct = ( opE . ct & ( ~ ( 7 < < 2 ) ) ) | ( block < < 2 ) ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputInt ( _ ( " FreqNum " ) , & freqNum , 1 , 16 ) ) {
2024-05-04 22:10:31 -05:00
if ( freqNum < 0 ) freqNum = 0 ;
if ( freqNum > 1023 ) freqNum = 1023 ;
opE . dt = freqNum & 0xff ;
opE . ct = ( opE . ct & ( ~ 3 ) ) | ( freqNum > > 8 ) ;
2023-10-22 11:46:34 -03:00
}
2024-05-04 22:10:31 -05:00
} else {
if ( ImGui : : BeginTable ( " amVibCheckboxes " , 2 , ImGuiTableFlags_SizingStretchSame ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthStretch , 0.0 ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch , 0.0 ) ;
float yCoordBeforeTablePadding = ImGui : : GetCursorPosY ( ) ;
ImGui : : TableNextRow ( ) ;
2023-10-22 11:46:34 -03:00
ImGui : : TableNextColumn ( ) ;
2024-05-04 22:10:31 -05:00
ImGui : : SetCursorPosY ( yCoordBeforeTablePadding ) ;
if ( ImGui : : Checkbox ( FM_SHORT_NAME ( FM_AM ) , & amOn ) ) { PARAMETER
op . am = amOn ;
2023-10-22 11:46:34 -03:00
}
ImGui : : TableNextColumn ( ) ;
2024-05-04 22:10:31 -05:00
ImGui : : SetCursorPosY ( yCoordBeforeTablePadding ) ;
if ( ImGui : : Checkbox ( FM_SHORT_NAME ( FM_VIB ) , & vibOn ) ) { PARAMETER
op . vib = vibOn ;
2023-10-22 11:46:34 -03:00
}
2024-05-04 22:10:31 -05:00
bool damOn = op . dam ;
bool dvbOn = op . dvb ;
ImGui : : TableNextRow ( ) ;
2023-10-22 11:46:34 -03:00
ImGui : : TableNextColumn ( ) ;
2024-05-04 22:10:31 -05:00
if ( ImGui : : Checkbox ( FM_SHORT_NAME ( FM_DAM ) , & damOn ) ) { PARAMETER
op . dam = damOn ;
2023-08-20 20:18:27 -05:00
}
2022-02-26 03:27:37 -05:00
ImGui : : TableNextColumn ( ) ;
2024-05-04 22:10:31 -05:00
if ( ImGui : : Checkbox ( FM_SHORT_NAME ( FM_DVB ) , & dvbOn ) ) { PARAMETER
op . dvb = dvbOn ;
2023-08-20 20:18:27 -05:00
}
2024-05-04 22:10:31 -05:00
ImGui : : EndTable ( ) ;
2022-02-26 03:27:37 -05:00
}
}
2022-02-17 13:08:17 -05:00
}
2024-05-04 22:10:31 -05:00
} else if ( ins - > type ! = DIV_INS_OPM ) {
ImGui : : TableNextColumn ( ) ;
bool amOn = op . am ;
ImGui : : SetCursorPosY ( ImGui : : GetCursorPosY ( ) + 0.5 * ( sliderHeight - ImGui : : GetFrameHeight ( ) * 4.0 - ImGui : : GetStyle ( ) . ItemSpacing . y * 3.0 ) ) ;
if ( ImGui : : Checkbox ( FM_NAME ( FM_AM ) , & amOn ) ) { PARAMETER
op . am = amOn ;
}
if ( ImGui : : Checkbox ( FM_NAME ( FM_VIB ) , & vibOn ) ) { PARAMETER
op . vib = vibOn ;
}
if ( ImGui : : Checkbox ( FM_NAME ( FM_KSR ) , & ksrOn ) ) { PARAMETER
op . ksr = ksrOn ;
}
if ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS ) {
if ( ImGui : : Checkbox ( FM_NAME ( FM_SUS ) , & susOn ) ) { PARAMETER
op . sus = susOn ;
2022-03-04 01:18:16 -05:00
}
2024-05-04 22:10:31 -05:00
} else if ( ins - > type = = DIV_INS_OPLL ) {
if ( ImGui : : Checkbox ( FM_NAME ( FM_EGS ) , & ssgOn ) ) { PARAMETER
op . ssgEnv = ( op . ssgEnv & 7 ) | ( ssgOn < < 3 ) ;
2022-03-04 01:18:16 -05:00
}
2022-02-26 03:27:37 -05:00
}
2024-05-04 22:10:31 -05:00
}
2022-02-26 03:27:37 -05:00
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_ESFM ) {
ImGui : : TableNextColumn ( ) ;
ImGui : : Dummy ( ImVec2 ( 4.0f * dpiScale , 2.0f * dpiScale ) ) ;
ImGui : : TableNextColumn ( ) ;
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
drawWaveform ( op . ws & 7 , ins - > type = = DIV_INS_OPZ , ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , sliderHeight - ImGui : : GetFrameHeightWithSpacing ( ) * ( ( ins - > type = = DIV_INS_ESFM & & fixedOn ) ? 3.0f : 1.0f ) ) ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( " ##WS " , ImGuiDataType_U8 , & op . ws , & _ZERO , & _SEVEN , ( ins - > type = = DIV_INS_OPZ ) ? opzWaveforms [ op . ws & 7 ] : ( settings . oplStandardWaveNames ? oplWaveformsStandard [ op . ws & 7 ] : oplWaveforms [ op . ws & 7 ] ) ) ) ; rightClickable
if ( ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS ) & & ImGui : : IsItemHovered ( ) ) {
2024-09-09 20:26:59 +09:00
ImGui : : SetTooltip ( _ ( " OPL2/3/4 only (last 4 waveforms are OPL3/4 only) " ) ) ;
2024-05-04 22:10:31 -05:00
}
if ( ins - > type = = DIV_INS_ESFM & & fixedOn ) {
if ( ImGui : : Checkbox ( FM_SHORT_NAME ( FM_VIB ) , & vibOn ) ) { PARAMETER
op . vib = vibOn ;
}
bool dvbOn = op . dvb ;
if ( ImGui : : Checkbox ( FM_SHORT_NAME ( FM_DVB ) , & dvbOn ) ) { PARAMETER
op . dvb = dvbOn ;
2022-11-15 17:51:43 -05:00
}
2022-02-26 03:27:37 -05:00
}
2024-05-04 22:10:31 -05:00
} else if ( ins - > type = = DIV_INS_OPLL | | ins - > type = = DIV_INS_OPM ) {
ImGui : : TableNextColumn ( ) ;
ImGui : : Dummy ( ImVec2 ( 4.0f * dpiScale , 2.0f * dpiScale ) ) ;
}
2022-03-27 18:30:46 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
drawFMEnv ( op . tl & maxTl , op . ar & maxArDr , op . dr & maxArDr , ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS | | ins - > type = = DIV_INS_OPLL | | ins - > type = = DIV_INS_ESFM ) ? ( ( op . rr & 15 ) * 2 ) : op . d2r & 31 , op . rr & 15 , op . sl & 15 , op . sus , op . ssgEnv & 8 , fmOrigin . alg , maxTl , maxArDr , 15 , ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , sliderHeight ) , ins - > type ) ;
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
if ( settings . separateFMColors ) {
popAccentColors ( ) ;
}
2023-10-14 08:10:37 -03:00
2024-05-04 22:10:31 -05:00
ImGui : : PopID ( ) ;
}
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : EndTable ( ) ;
}
} else if ( settings . fmLayout > = 4 & & settings . fmLayout < = 6 ) { // alternate
int columns = 2 ;
switch ( settings . fmLayout ) {
case 4 : // 2x2
columns = 2 ;
break ;
case 5 : // 1x4
columns = 1 ;
break ;
case 6 : // 4x1
columns = opCount ;
break ;
}
char tempID [ 1024 ] ;
ImVec2 oldPadding = ImGui : : GetStyle ( ) . CellPadding ;
ImGui : : PushStyleVar ( ImGuiStyleVar_CellPadding , ImVec2 ( 8.0f * dpiScale , 4.0f * dpiScale ) ) ;
if ( ImGui : : BeginTable ( " AltFMOperators " , columns , ImGuiTableFlags_SizingStretchSame | ImGuiTableFlags_BordersInner ) ) {
for ( int i = 0 ; i < opCount ; i + + ) {
DivInstrumentFM : : Operator & op = fmOrigin . op [ ( opCount = = 4 & & ins - > type ! = DIV_INS_OPL_DRUMS & & ins - > type ! = DIV_INS_ESFM ) ? opOrder [ i ] : i ] ;
DivInstrumentESFM : : Operator & opE = ins - > esfm . op [ i ] ;
if ( ( settings . fmLayout ! = 6 & & ( ( i + 1 ) & 1 ) ) | | i = = 0 | | settings . fmLayout = = 5 ) ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : PushID ( fmt : : sprintf ( " op%d " , i ) . c_str ( ) ) ;
// push colors
if ( settings . separateFMColors ) {
bool mod = true ;
if ( ins - > type = = DIV_INS_OPL_DRUMS ) {
mod = false ;
} else if ( ins - > type = = DIV_INS_ESFM ) {
// this is the same as the KVS heuristic in platform/esfm.h
if ( opE . outLvl = = 7 ) mod = false ;
else if ( opE . outLvl > 0 ) {
if ( i = = 3 ) mod = false ;
else {
DivInstrumentESFM : : Operator & opENext = ins - > esfm . op [ i + 1 ] ;
if ( opENext . modIn = = 0 ) mod = false ;
else if ( ( opE . outLvl - opENext . modIn ) > = 2 ) mod = false ;
2022-11-15 17:51:43 -05:00
}
2024-05-04 22:10:31 -05:00
}
} else if ( opCount = = 4 ) {
if ( ins - > type = = DIV_INS_OPL ) {
if ( opIsOutputOPL [ fmOrigin . alg & 3 ] [ i ] ) mod = false ;
} else {
if ( opIsOutput [ fmOrigin . alg & 7 ] [ i ] ) mod = false ;
}
} else {
if ( i = = 1 | | ( ins - > type = = DIV_INS_OPL & & ( fmOrigin . alg & 1 ) ) ) mod = false ;
}
if ( mod ) {
pushAccentColors (
uiColors [ GUI_COLOR_FM_PRIMARY_MOD ] ,
uiColors [ GUI_COLOR_FM_SECONDARY_MOD ] ,
uiColors [ GUI_COLOR_FM_BORDER_MOD ] ,
uiColors [ GUI_COLOR_FM_BORDER_SHADOW_MOD ]
) ;
} else {
pushAccentColors (
uiColors [ GUI_COLOR_FM_PRIMARY_CAR ] ,
uiColors [ GUI_COLOR_FM_SECONDARY_CAR ] ,
uiColors [ GUI_COLOR_FM_BORDER_CAR ] ,
uiColors [ GUI_COLOR_FM_BORDER_SHADOW_CAR ]
) ;
}
}
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : Dummy ( ImVec2 ( dpiScale , dpiScale ) ) ;
if ( ins - > type = = DIV_INS_OPL_DRUMS ) {
snprintf ( tempID , 1024 , " %s " , oplDrumNames [ i ] ) ;
} else if ( ins - > type = = DIV_INS_OPL & & fmOrigin . opllPreset = = 16 ) {
if ( i = = 1 ) {
2024-05-26 19:31:17 -05:00
snprintf ( tempID , 1024 , _ ( " Envelope 2 (kick only) " ) ) ;
2024-05-04 22:10:31 -05:00
} else {
2024-05-26 19:31:17 -05:00
snprintf ( tempID , 1024 , _ ( " Envelope " ) ) ;
2024-05-04 22:10:31 -05:00
}
} else {
2024-05-26 19:31:17 -05:00
snprintf ( tempID , 1024 , _ ( " Operator %d " ) , i + 1 ) ;
2024-05-04 22:10:31 -05:00
}
float nextCursorPosX = ImGui : : GetCursorPosX ( ) + 0.5 * ( ImGui : : GetContentRegionAvail ( ) . x - ImGui : : CalcTextSize ( tempID ) . x - ( opsAreMutable ? ( ImGui : : GetStyle ( ) . FramePadding . x * 2.0f ) : 0.0f ) ) ;
OP_DRAG_POINT ;
ImGui : : SameLine ( ) ;
ImGui : : SetCursorPosX ( nextCursorPosX ) ;
if ( opsAreMutable ) {
pushToggleColors ( op . enable ) ;
if ( ImGui : : Button ( tempID ) ) {
op . enable = ! op . enable ;
PARAMETER ;
}
popToggleColors ( ) ;
} else {
ImGui : : TextUnformatted ( tempID ) ;
}
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
float sliderHeight = 200.0f * dpiScale ;
float waveWidth = 140.0 * dpiScale * ( ( ins - > type = = DIV_INS_ESFM ) ? 0.85f : 1.0f ) ;
float waveHeight = sliderHeight - ImGui : : GetFrameHeightWithSpacing ( ) * ( ( ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_ESFM ) ? 5.0f : 4.5f ) ;
2023-10-14 08:10:37 -03:00
2024-05-04 22:10:31 -05:00
int maxTl = 127 ;
if ( ins - > type = = DIV_INS_OPLL ) {
if ( i = = 1 ) {
maxTl = 15 ;
} else {
maxTl = 63 ;
}
}
if ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS | | ins - > type = = DIV_INS_ESFM ) {
maxTl = 63 ;
}
int maxArDr = ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) ? 31 : 15 ;
bool ssgOn = op . ssgEnv & 8 ;
bool ksrOn = op . ksr ;
bool vibOn = op . vib ;
bool egtOn = op . egt ;
bool susOn = op . sus ; // yawn
unsigned char ssgEnv = op . ssgEnv & 7 ;
ImGui : : PushStyleVar ( ImGuiStyleVar_CellPadding , oldPadding ) ;
if ( ImGui : : BeginTable ( " opParams " , 4 , ImGuiTableFlags_BordersInnerV ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthFixed , waveWidth ) ;
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthStretch ) ;
ImGui : : TableSetupColumn ( " c3 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
float textY = ImGui : : GetCursorPosY ( ) ;
if ( ins - > type = = DIV_INS_ESFM ) {
CENTER_TEXT_20 ( ESFM_SHORT_NAME ( ESFM_DELAY ) ) ;
ImGui : : TextUnformatted ( ESFM_SHORT_NAME ( ESFM_DELAY ) ) ;
TOOLTIP_TEXT ( ESFM_LONG_NAME ( ESFM_DELAY ) ) ;
} else {
CENTER_TEXT_20 ( FM_SHORT_NAME ( FM_AR ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_AR ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_AR ) ) ;
}
ImGui : : TableNextColumn ( ) ;
if ( ins - > type = = DIV_INS_FM ) {
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " SSG-EG " ) ) ;
2024-07-06 19:21:32 -05:00
} else if ( ins - > type ! = DIV_INS_OPM ) {
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Waveform " ) ) ;
2024-05-04 22:10:31 -05:00
}
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Envelope " ) ) ;
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
// A/D/S/R
ImGui : : TableNextColumn ( ) ;
2022-04-07 00:45:53 -05:00
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_ESFM ) {
opE . delay & = 7 ;
P ( CWVSliderScalar ( " ##DELAY " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & opE . delay , & _ZERO , & _SEVEN ) ) ; rightClickable
ImGui : : SameLine ( ) ;
}
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
op . ar & = maxArDr ;
float textX_AR = ImGui : : GetCursorPosX ( ) ;
P ( CWVSliderScalar ( " ##AR " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . ar , & maxArDr , & _ZERO ) ) ; rightClickable
2023-10-14 08:10:37 -03:00
2024-05-04 22:10:31 -05:00
ImGui : : SameLine ( ) ;
op . dr & = maxArDr ;
float textX_DR = ImGui : : GetCursorPosX ( ) ;
P ( CWVSliderScalar ( " ##DR " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . dr , & maxArDr , & _ZERO ) ) ; rightClickable
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
float textX_SL = 0.0f ;
if ( settings . susPosition = = 0 ) {
ImGui : : SameLine ( ) ;
op . sl & = 15 ;
textX_SL = ImGui : : GetCursorPosX ( ) ;
P ( CWVSliderScalar ( " ##SL " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . sl , & _FIFTEEN , & _ZERO ) ) ; rightClickable
}
2022-03-26 17:30:26 -05:00
2024-05-04 22:10:31 -05:00
float textX_D2R = 0.0f ;
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) {
ImGui : : SameLine ( ) ;
op . d2r & = 31 ;
textX_D2R = ImGui : : GetCursorPosX ( ) ;
P ( CWVSliderScalar ( " ##D2R " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . d2r , & _THIRTY_ONE , & _ZERO ) ) ; rightClickable
}
2022-02-23 11:51:02 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : SameLine ( ) ;
op . rr & = 15 ;
float textX_RR = ImGui : : GetCursorPosX ( ) ;
P ( CWVSliderScalar ( " ##RR " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . rr , & _FIFTEEN , & _ZERO ) ) ; rightClickable
2022-11-15 17:51:43 -05:00
2024-07-25 19:36:40 -05:00
if ( settings . susPosition > 0 ) {
2024-05-04 22:10:31 -05:00
ImGui : : SameLine ( ) ;
op . sl & = 15 ;
textX_SL = ImGui : : GetCursorPosX ( ) ;
P ( CWVSliderScalar ( " ##SL " , ImVec2 ( 20.0f * dpiScale , sliderHeight ) , ImGuiDataType_U8 , & op . sl , & _FIFTEEN , & _ZERO ) ) ; rightClickable
}
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
ImVec2 prevCurPos = ImGui : : GetCursorPos ( ) ;
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
// labels
if ( ins - > type = = DIV_INS_ESFM ) {
ImGui : : SetCursorPos ( ImVec2 ( textX_AR , textY ) ) ;
CENTER_TEXT_20 ( FM_SHORT_NAME ( FM_AR ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_AR ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_AR ) ) ;
}
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : SetCursorPos ( ImVec2 ( textX_DR , textY ) ) ;
CENTER_TEXT_20 ( FM_SHORT_NAME ( FM_DR ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_DR ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_DR ) ) ;
ImGui : : SetCursorPos ( ImVec2 ( textX_SL , textY ) ) ;
CENTER_TEXT_20 ( FM_SHORT_NAME ( FM_SL ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_SL ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_SL ) ) ;
ImGui : : SetCursorPos ( ImVec2 ( textX_RR , textY ) ) ;
CENTER_TEXT_20 ( FM_SHORT_NAME ( FM_RR ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_RR ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_RR ) ) ;
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) {
ImGui : : SetCursorPos ( ImVec2 ( textX_D2R , textY ) ) ;
CENTER_TEXT_20 ( FM_SHORT_NAME ( FM_D2R ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_D2R ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_D2R ) ) ;
}
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : SetCursorPos ( prevCurPos ) ;
ImGui : : TableNextColumn ( ) ;
switch ( ins - > type ) {
case DIV_INS_FM : {
// SSG
ImGui : : BeginDisabled ( ! ssgOn ) ;
drawSSGEnv ( op . ssgEnv & 7 , ImVec2 ( waveWidth , waveHeight ) ) ;
ImGui : : EndDisabled ( ) ;
if ( ImGui : : Checkbox ( " ##SSGOn " , & ssgOn ) ) { PARAMETER
op . ssgEnv = ( op . ssgEnv & 7 ) | ( ssgOn < < 3 ) ;
}
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : SameLine ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
2024-05-26 19:31:17 -05:00
if ( CWSliderScalar ( " ##SSG " , ImGuiDataType_U8 , & ssgEnv , & _ZERO , & _SEVEN , _ ( ssgEnvTypes [ ssgEnv ] ) ) ) { PARAMETER
2024-05-04 22:10:31 -05:00
op . ssgEnv = ( op . ssgEnv & 8 ) | ( ssgEnv & 7 ) ;
}
// params
ImGui : : Separator ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_MULT ) ) ;
P ( CWSliderScalar ( " ##MULT " , ImGuiDataType_U8 , & op . mult , & _ZERO , & _FIFTEEN , tempID ) ) ; rightClickable
int detune = detuneMap [ settings . unsignedDetune ? 1 : 0 ] [ op . dt & 7 ] ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_DT ) ) ;
if ( CWSliderInt ( " ##DT " , & detune , settings . unsignedDetune ? 0 : - 3 , settings . unsignedDetune ? 7 : 4 , tempID ) ) { PARAMETER
if ( detune < - 3 ) detune = - 3 ;
if ( detune > 7 ) detune = 7 ;
op . dt = detuneUnmap [ settings . unsignedDetune ? 1 : 0 ] [ detune + 3 ] ;
} rightClickable
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_RS ) ) ;
P ( CWSliderScalar ( " ##RS " , ImGuiDataType_U8 , & op . rs , & _ZERO , & _THREE , tempID ) ) ; rightClickable
break ;
}
case DIV_INS_OPM : {
// params
ImGui : : Separator ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_MULT ) ) ;
P ( CWSliderScalar ( " ##MULT " , ImGuiDataType_U8 , & op . mult , & _ZERO , & _FIFTEEN , tempID ) ) ; rightClickable
int detune = detuneMap [ settings . unsignedDetune ? 1 : 0 ] [ op . dt & 7 ] ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_DT ) ) ;
if ( CWSliderInt ( " ##DT " , & detune , settings . unsignedDetune ? 0 : - 3 , settings . unsignedDetune ? 7 : 4 , tempID ) ) { PARAMETER
if ( detune < - 3 ) detune = - 3 ;
if ( detune > 7 ) detune = 7 ;
op . dt = detuneUnmap [ settings . unsignedDetune ? 1 : 0 ] [ detune + 3 ] ;
} rightClickable
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_DT2 ) ) ;
P ( CWSliderScalar ( " ##DT2 " , ImGuiDataType_U8 , & op . dt2 , & _ZERO , & _THREE , tempID ) ) ; rightClickable
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_RS ) ) ;
P ( CWSliderScalar ( " ##RS " , ImGuiDataType_U8 , & op . rs , & _ZERO , & _THREE , tempID ) ) ; rightClickable
break ;
}
case DIV_INS_OPLL :
// waveform
drawWaveform ( i = = 0 ? ( fmOrigin . ams & 1 ) : ( fmOrigin . fms & 1 ) , ins - > type = = DIV_INS_OPZ , ImVec2 ( waveWidth , waveHeight ) ) ;
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
// params
ImGui : : Separator ( ) ;
if ( ImGui : : BeginTable ( " FMParamsInner " , 2 ) ) {
ImGui : : TableNextRow ( ) ;
2022-02-23 11:51:02 -05:00
ImGui : : TableNextColumn ( ) ;
2024-05-04 22:10:31 -05:00
bool amOn = op . am ;
if ( ImGui : : Checkbox ( FM_NAME ( FM_AM ) , & amOn ) ) { PARAMETER
op . am = amOn ;
2022-03-25 18:16:47 -05:00
}
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : Checkbox ( FM_NAME ( FM_KSR ) , & ksrOn ) ) { PARAMETER
op . ksr = ksrOn ;
2022-04-07 00:45:53 -05:00
}
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : Checkbox ( FM_NAME ( FM_VIB ) , & vibOn ) ) { PARAMETER
op . vib = vibOn ;
2023-10-14 08:10:37 -03:00
}
2022-02-23 11:51:02 -05:00
ImGui : : TableNextColumn ( ) ;
2024-05-04 22:10:31 -05:00
if ( ImGui : : Checkbox ( FM_NAME ( FM_EGS ) , & ssgOn ) ) { PARAMETER
op . ssgEnv = ( op . ssgEnv & 7 ) | ( ssgOn < < 3 ) ;
2022-04-07 00:45:53 -05:00
}
2024-05-04 22:10:31 -05:00
ImGui : : EndTable ( ) ;
}
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_MULT ) ) ;
P ( CWSliderScalar ( " ##MULT " , ImGuiDataType_U8 , & op . mult , & _ZERO , & _FIFTEEN , tempID ) ) ; rightClickable
2023-10-14 08:10:37 -03:00
2024-05-04 22:10:31 -05:00
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_KSL ) ) ;
P ( CWSliderScalar ( " ##KSL " , ImGuiDataType_U8 , & op . ksl , & _ZERO , & _THREE , tempID ) ) ; rightClickable
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
break ;
case DIV_INS_OPL :
case DIV_INS_OPL_DRUMS : {
// waveform
drawWaveform ( op . ws & 7 , ins - > type = = DIV_INS_OPZ , ImVec2 ( waveWidth , waveHeight ) ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( " ##WS " , ImGuiDataType_U8 , & op . ws , & _ZERO , & _SEVEN , ( ins - > type = = DIV_INS_OPZ ) ? opzWaveforms [ op . ws & 7 ] : ( settings . oplStandardWaveNames ? oplWaveformsStandard [ op . ws & 7 ] : oplWaveforms [ op . ws & 7 ] ) ) ) ; rightClickable
if ( ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS ) & & ImGui : : IsItemHovered ( ) ) {
2024-09-09 20:26:59 +09:00
ImGui : : SetTooltip ( _ ( " OPL2/3/4 only (last 4 waveforms are OPL3/4 only) " ) ) ;
2024-05-04 22:10:31 -05:00
}
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
// params
ImGui : : Separator ( ) ;
if ( ImGui : : BeginTable ( " FMParamsInner " , 2 ) ) {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
bool amOn = op . am ;
if ( ImGui : : Checkbox ( FM_NAME ( FM_AM ) , & amOn ) ) { PARAMETER
op . am = amOn ;
}
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : Checkbox ( FM_NAME ( FM_KSR ) , & ksrOn ) ) { PARAMETER
op . ksr = ksrOn ;
}
2023-10-14 08:10:37 -03:00
2024-05-04 22:10:31 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : Checkbox ( FM_NAME ( FM_VIB ) , & vibOn ) ) { PARAMETER
op . vib = vibOn ;
}
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : Checkbox ( FM_NAME ( FM_SUS ) , & susOn ) ) { PARAMETER
op . sus = susOn ;
2022-03-27 18:30:46 -05:00
}
2024-05-04 22:10:31 -05:00
ImGui : : EndTable ( ) ;
}
2022-11-15 17:51:43 -05:00
2024-11-11 03:57:23 -05:00
pushWarningColor ( ins - > type = = DIV_INS_OPL_DRUMS & & i = = 0 ) ;
2024-05-04 22:10:31 -05:00
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_MULT ) ) ;
P ( CWSliderScalar ( " ##MULT " , ImGuiDataType_U8 , & op . mult , & _ZERO , & _FIFTEEN , tempID ) ) ; rightClickable
2024-11-11 03:57:23 -05:00
if ( ins - > type = = DIV_INS_OPL_DRUMS & & i = = 0 ) {
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( " %s " , _ ( " Snare's multiplier is determined by HiHat's. " ) ) ;
}
}
popWarningColor ( ) ;
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_KSL ) ) ;
int ksl = kslMap [ op . ksl & 3 ] ;
if ( CWSliderInt ( " ##KSL " , & ksl , 0 , 3 , tempID ) ) {
op . ksl = kslMap [ ksl & 3 ] ;
PARAMETER ;
} rightClickable
2022-03-25 18:16:47 -05:00
2024-05-04 22:10:31 -05:00
break ;
}
case DIV_INS_OPZ : {
// waveform
drawWaveform ( op . ws & 7 , ins - > type = = DIV_INS_OPZ , ImVec2 ( waveWidth , waveHeight ) ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( " ##WS " , ImGuiDataType_U8 , & op . ws , & _ZERO , & _SEVEN , ( ins - > type = = DIV_INS_OPZ ) ? opzWaveforms [ op . ws & 7 ] : ( settings . oplStandardWaveNames ? oplWaveformsStandard [ op . ws & 7 ] : oplWaveforms [ op . ws & 7 ] ) ) ) ; rightClickable
if ( ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS ) & & ImGui : : IsItemHovered ( ) ) {
2024-09-09 20:26:59 +09:00
ImGui : : SetTooltip ( _ ( " OPL2/3/4 only (last 4 waveforms are OPL3/4 only) " ) ) ;
2024-05-04 22:10:31 -05:00
}
2022-03-25 18:16:47 -05:00
2024-05-04 22:10:31 -05:00
// params
ImGui : : Separator ( ) ;
if ( egtOn ) {
2024-09-22 03:58:17 -05:00
if ( ! op . sus ) {
2024-08-25 17:26:59 +03:00
int block = op . dt ;
int freqNum = ( op . mult < < 4 ) | ( op . dvb & 15 ) ;
ImGui : : Text ( _ ( " Block " ) ) ;
ImGui : : SameLine ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
ImVec2 cursorAlign = ImGui : : GetCursorPos ( ) ;
if ( ImGui : : InputInt ( " ##Block " , & block , 1 , 1 ) ) {
if ( block < 0 ) block = 0 ;
if ( block > 7 ) block = 7 ;
op . dt = block ;
}
ImGui : : Text ( _ ( " Freq " ) ) ;
ImGui : : SameLine ( ) ;
ImGui : : SetCursorPos ( ImVec2 ( cursorAlign . x , ImGui : : GetCursorPosY ( ) ) ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( ImGui : : InputInt ( " ##FreqNum " , & freqNum , 1 , 16 ) ) {
if ( freqNum < 0 ) freqNum = 0 ;
if ( freqNum > 255 ) freqNum = 255 ;
op . mult = freqNum > > 4 ;
op . dvb = freqNum & 15 ;
}
2022-11-15 17:51:43 -05:00
}
2024-05-04 22:10:31 -05:00
} else {
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_MULT ) ) ;
P ( CWSliderScalar ( " ##MULT " , ImGuiDataType_U8 , & op . mult , & _ZERO , & _FIFTEEN , tempID ) ) ; rightClickable
2022-03-25 18:16:47 -05:00
2024-05-04 22:10:31 -05:00
int detune = detuneMap [ settings . unsignedDetune ? 1 : 0 ] [ op . dt & 7 ] ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_DT ) ) ;
if ( CWSliderInt ( " ##DT " , & detune , settings . unsignedDetune ? 0 : - 3 , settings . unsignedDetune ? 7 : 4 , tempID ) ) { PARAMETER
if ( detune < - 3 ) detune = - 3 ;
if ( detune > 7 ) detune = 7 ;
op . dt = detuneUnmap [ settings . unsignedDetune ? 1 : 0 ] [ detune + 3 ] ;
} rightClickable
2022-11-15 17:51:43 -05:00
}
2022-04-12 18:26:25 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_DT2 ) ) ;
P ( CWSliderScalar ( " ##DT2 " , ImGuiDataType_U8 , & op . dt2 , & _ZERO , & _THREE , tempID ) ) ; rightClickable
if ( ImGui : : IsItemHovered ( ) ) {
2024-08-25 18:19:39 +03:00
ImGui : : SetTooltip ( _ ( " Only on YM2151 and YM2414 (OPM and OPZ) " ) ) ;
2024-05-04 22:10:31 -05:00
}
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_RS ) ) ;
P ( CWSliderScalar ( " ##RS " , ImGuiDataType_U8 , & op . rs , & _ZERO , & _THREE , tempID ) ) ; rightClickable
break ;
2022-11-15 17:51:43 -05:00
}
2024-05-04 22:10:31 -05:00
case DIV_INS_ESFM :
// waveform
drawWaveform ( op . ws & 7 , ins - > type = = DIV_INS_OPZ , ImVec2 ( waveWidth , waveHeight ) ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( " ##WS " , ImGuiDataType_U8 , & op . ws , & _ZERO , & _SEVEN , ( ins - > type = = DIV_INS_OPZ ) ? opzWaveforms [ op . ws & 7 ] : ( settings . oplStandardWaveNames ? oplWaveformsStandard [ op . ws & 7 ] : oplWaveforms [ op . ws & 7 ] ) ) ) ; rightClickable
// params
ImGui : : Separator ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_MULT ) ) ;
P ( CWSliderScalar ( " ##MULT " , ImGuiDataType_U8 , & op . mult , & _ZERO , & _FIFTEEN , tempID ) ) ; rightClickable
if ( opE . fixed ) {
int block = ( opE . ct > > 2 ) & 7 ;
int freqNum = ( ( opE . ct & 3 ) < < 8 ) | ( ( unsigned char ) opE . dt ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Blk " ) ) ;
2024-05-04 22:10:31 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Block " ) ) ;
2024-05-04 22:10:31 -05:00
}
ImGui : : SameLine ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
//ImVec2 cursorAlign=ImGui::GetCursorPos();
if ( ImGui : : InputInt ( " ##Block " , & block , 1 , 1 ) ) {
if ( block < 0 ) block = 0 ;
if ( block > 7 ) block = 7 ;
opE . ct = ( opE . ct & ( ~ ( 7 < < 2 ) ) ) | ( block < < 2 ) ;
2022-11-15 17:51:43 -05:00
}
2022-03-25 18:16:47 -05:00
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " F " ) ) ;
2024-05-04 22:10:31 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Frequency (F-Num) " ) ) ;
2022-11-15 17:51:43 -05:00
}
ImGui : : SameLine ( ) ;
2024-05-04 22:10:31 -05:00
//ImGui::SetCursorPos(ImVec2(cursorAlign.x,ImGui::GetCursorPosY()));
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( ImGui : : InputInt ( " ##FreqNum " , & freqNum , 1 , 16 ) ) {
if ( freqNum < 0 ) freqNum = 0 ;
if ( freqNum > 1023 ) freqNum = 1023 ;
opE . dt = freqNum & 0xff ;
opE . ct = ( opE . ct & ( ~ 3 ) ) | ( freqNum > > 8 ) ;
2022-11-15 17:51:43 -05:00
}
2024-05-04 22:10:31 -05:00
} else {
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , ESFM_NAME ( ESFM_CT ) ) ;
P ( CWSliderScalar ( " ##CT " , ImGuiDataType_S8 , & opE . ct , & _MINUS_TWENTY_FOUR , & _TWENTY_FOUR , tempID ) ) ; rightClickable
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , ESFM_NAME ( ESFM_DT ) ) ;
P ( CWSliderScalar ( " ##DT " , ImGuiDataType_S8 , & opE . dt , & _MINUS_ONE_HUNDRED_TWENTY_EIGHT , & _ONE_HUNDRED_TWENTY_SEVEN , tempID ) ) ; rightClickable
}
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
if ( ImGui : : BeginTable ( " panCheckboxes " , 2 , ImGuiTableFlags_SizingStretchSame ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthStretch , 0.0f ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch , 0.0f ) ;
float yPosOutsideTablePadding = ImGui : : GetCursorPosY ( ) ;
bool leftOn = opE . left ;
bool rightOn = opE . right ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetCursorPosY ( yPosOutsideTablePadding ) ;
if ( ImGui : : Checkbox ( ESFM_SHORT_NAME ( ESFM_LEFT ) , & leftOn ) ) { PARAMETER
opE . left = leftOn ;
2022-11-15 17:51:43 -05:00
}
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : SetCursorPosY ( yPosOutsideTablePadding ) ;
if ( ImGui : : Checkbox ( ESFM_SHORT_NAME ( ESFM_RIGHT ) , & rightOn ) ) { PARAMETER
opE . right = rightOn ;
2022-11-15 17:51:43 -05:00
}
2024-05-04 22:10:31 -05:00
ImGui : : EndTable ( ) ;
}
break ;
default :
break ;
}
2022-03-25 18:16:47 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
float envHeight = sliderHeight ; //-ImGui::GetStyle().ItemSpacing.y*2.0f;
if ( ins - > type = = DIV_INS_OPZ ) {
envHeight - = ImGui : : GetFrameHeightWithSpacing ( ) * 2.0f ;
}
if ( ins - > type = = DIV_INS_ESFM ) {
envHeight - = ImGui : : GetFrameHeightWithSpacing ( ) * 3.0f ;
}
drawFMEnv ( op . tl & maxTl , op . ar & maxArDr , op . dr & maxArDr , ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS | | ins - > type = = DIV_INS_OPLL | | ins - > type = = DIV_INS_ESFM ) ? ( ( op . rr & 15 ) * 2 ) : op . d2r & 31 , op . rr & 15 , op . sl & 15 , op . sus , op . ssgEnv & 8 , fmOrigin . alg , maxTl , maxArDr , 15 , ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , envHeight ) , ins - > type ) ;
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_OPZ ) {
ImGui : : Separator ( ) ;
if ( ImGui : : BeginTable ( " FMParamsInnerOPZ " , 2 ) ) {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
if ( ! egtOn ) {
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_FINE ) ) ;
P ( CWSliderScalar ( " ##FINE " , ImGuiDataType_U8 , & op . dvb , & _ZERO , & _FIFTEEN , tempID ) ) ; rightClickable
2024-09-22 03:58:17 -05:00
} else {
2024-08-25 13:33:01 +03:00
bool susOn = op . sus ;
2025-10-22 14:00:52 -05:00
pushWarningColor ( susOn & & ! e - > song . linearPitch ) ;
2024-09-22 16:56:54 -05:00
if ( ImGui : : Checkbox ( _ ( " Pitch control " ) , & susOn ) ) { PARAMETER
2024-08-25 13:33:01 +03:00
op . sus = susOn ;
2024-08-25 17:26:59 +03:00
// HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly
2025-03-10 12:35:05 -05:00
ins - > temp . vZoom [ DIV_MACRO_OP_SSG + ( i < < 5 ) ] = - 1 ;
ins - > temp . vZoom [ DIV_MACRO_OP_SUS + ( i < < 5 ) ] = - 1 ;
2024-08-25 13:33:01 +03:00
}
2024-09-22 16:56:54 -05:00
popWarningColor ( ) ;
2024-09-22 03:58:17 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2025-10-22 14:00:52 -05:00
if ( susOn & & ! e - > song . linearPitch ) {
2024-09-22 16:56:54 -05:00
ImGui : : SetTooltip ( _ ( " only works on linear pitch! go to Compatibility Flags > Pitch/Playback and set Pitch linearity to Full. " ) ) ;
} else {
ImGui : : SetTooltip ( _ ( " use op's arpeggio and pitch macros control instead of block/f-num macros " ) ) ;
}
2024-08-25 13:33:01 +03:00
}
}
2023-10-14 14:00:31 -03:00
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
bool amOn = op . am ;
if ( ImGui : : Checkbox ( FM_NAME ( FM_AM ) , & amOn ) ) { PARAMETER
op . am = amOn ;
}
ImGui : : SameLine ( ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Checkbox ( _ ( " Fixed " ) , & egtOn ) ) { PARAMETER
2024-05-04 22:10:31 -05:00
op . egt = egtOn ;
}
2022-03-25 18:16:47 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_EGSHIFT ) ) ;
P ( CWSliderScalar ( " ##EGShift " , ImGuiDataType_U8 , & op . ksl , & _ZERO , & _THREE , tempID ) ) ; rightClickable
2022-03-25 18:16:47 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_REV ) ) ;
P ( CWSliderScalar ( " ##REV " , ImGuiDataType_U8 , & op . dam , & _ZERO , & _SEVEN , tempID ) ) ; rightClickable
2022-02-23 11:51:02 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
2022-03-27 03:38:04 -05:00
2023-10-14 14:00:31 -03:00
2024-05-04 22:10:31 -05:00
ImGui : : EndTable ( ) ;
}
}
2023-10-14 14:00:31 -03:00
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_ESFM ) {
ImGui : : Separator ( ) ;
if ( ImGui : : BeginTable ( " FMParamsInnerESFM " , 2 ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthStretch , 0.64f ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch , 0.36f ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2022-03-08 13:12:20 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
snprintf ( tempID , 1024 , " %s: %%d " , FM_NAME ( FM_KSL ) ) ;
int ksl = kslMap [ op . ksl & 3 ] ;
if ( CWSliderInt ( " ##KSL " , & ksl , 0 , 3 , tempID ) ) {
op . ksl = kslMap [ ksl & 3 ] ;
PARAMETER ;
} rightClickable
2022-06-13 03:54:42 -05:00
2024-05-04 22:10:31 -05:00
bool amOn = op . am ;
bool fixedOn = opE . fixed ;
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : Checkbox ( FM_SHORT_NAME ( FM_KSR ) , & ksrOn ) ) { PARAMETER
op . ksr = ksrOn ;
}
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : BeginTable ( " vibAmCheckboxes " , 2 ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthStretch , 0.0f ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch , 0.0f ) ;
2023-10-14 14:00:31 -03:00
2024-05-04 22:10:31 -05:00
float yPosOutsideTablePadding = ImGui : : GetCursorPosY ( ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetCursorPosY ( yPosOutsideTablePadding ) ;
if ( ImGui : : Checkbox ( FM_SHORT_NAME ( FM_VIB ) , & vibOn ) ) { PARAMETER
op . vib = vibOn ;
2022-11-15 17:51:43 -05:00
}
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : SetCursorPosY ( yPosOutsideTablePadding ) ;
if ( ImGui : : Checkbox ( FM_SHORT_NAME ( FM_AM ) , & amOn ) ) { PARAMETER
op . am = amOn ;
2022-06-13 03:54:42 -05:00
}
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
bool damOn = op . dam ;
bool dvbOn = op . dvb ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : Checkbox ( FM_SHORT_NAME ( FM_DVB ) , & dvbOn ) ) { PARAMETER
op . dvb = dvbOn ;
}
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : Checkbox ( FM_SHORT_NAME ( FM_DAM ) , & damOn ) ) { PARAMETER
op . dam = damOn ;
}
ImGui : : EndTable ( ) ;
2022-03-25 18:16:47 -05:00
}
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : Checkbox ( FM_SHORT_NAME ( FM_SUS ) , & susOn ) ) { PARAMETER
op . sus = susOn ;
}
if ( ImGui : : Checkbox ( ESFM_NAME ( ESFM_FIXED ) , & fixedOn ) ) { PARAMETER
opE . fixed = fixedOn ;
// HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly
2025-03-10 12:35:05 -05:00
ins - > temp . vZoom [ DIV_MACRO_OP_SSG + ( i < < 5 ) ] = - 1 ;
ins - > temp . vZoom [ DIV_MACRO_OP_DT + ( i < < 5 ) ] = - 1 ;
2024-05-04 22:10:31 -05:00
}
2022-11-15 17:51:43 -05:00
ImGui : : EndTable ( ) ;
}
2024-05-04 22:10:31 -05:00
}
ImGui : : TableNextColumn ( ) ;
op . tl & = maxTl ;
float tlSliderWidth = ( ins - > type = = DIV_INS_ESFM ) ? 20.0f * dpiScale : ImGui : : GetFrameHeight ( ) ;
float tlSliderHeight = sliderHeight - ( ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPM ) ? ( ImGui : : GetFrameHeightWithSpacing ( ) + ImGui : : CalcTextSize ( FM_SHORT_NAME ( FM_AM ) ) . y + ImGui : : GetStyle ( ) . ItemSpacing . y ) : 0.0f ) ;
float textX_tl = ImGui : : GetCursorPosX ( ) ;
P ( CWVSliderScalar ( " ##TL " , ImVec2 ( tlSliderWidth , tlSliderHeight ) , ImGuiDataType_U8 , & op . tl , & maxTl , & _ZERO ) ) ; rightClickable
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPM ) {
CENTER_TEXT ( FM_SHORT_NAME ( FM_AM ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_AM ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_AM ) ) ;
bool amOn = op . am ;
if ( ImGui : : Checkbox ( " ##AM " , & amOn ) ) { PARAMETER
op . am = amOn ;
2022-11-15 17:51:43 -05:00
}
2024-05-04 22:10:31 -05:00
}
2022-02-26 03:27:37 -05:00
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_ESFM ) {
ImGui : : SameLine ( ) ;
float textX_outLvl = ImGui : : GetCursorPosX ( ) ;
P ( CWVSliderScalar ( " ##OUTLVL " , ImVec2 ( tlSliderWidth , tlSliderHeight ) , ImGuiDataType_U8 , & opE . outLvl , & _ZERO , & _SEVEN ) ) ; rightClickable
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : SameLine ( ) ;
float textX_modIn = ImGui : : GetCursorPosX ( ) ;
P ( CWVSliderScalar ( " ##MODIN " , ImVec2 ( tlSliderWidth , tlSliderHeight ) , ImGuiDataType_U8 , & opE . modIn , & _ZERO , & _SEVEN ) ) ; rightClickable
prevCurPos = ImGui : : GetCursorPos ( ) ;
ImGui : : SetCursorPos ( ImVec2 ( textX_tl , textY ) ) ;
CENTER_TEXT_20 ( FM_SHORT_NAME ( FM_TL ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_TL ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_TL ) ) ;
ImGui : : SetCursorPos ( ImVec2 ( textX_outLvl , textY ) ) ;
CENTER_TEXT_20 ( ESFM_SHORT_NAME ( ESFM_OUTLVL ) ) ;
ImGui : : TextUnformatted ( ESFM_SHORT_NAME ( ESFM_OUTLVL ) ) ;
TOOLTIP_TEXT ( ESFM_LONG_NAME ( ESFM_OUTLVL ) ) ;
ImGui : : SetCursorPos ( ImVec2 ( textX_modIn , textY ) ) ;
CENTER_TEXT_20 ( ESFM_SHORT_NAME ( ESFM_MODIN ) ) ;
ImGui : : TextUnformatted ( ESFM_SHORT_NAME ( ESFM_MODIN ) ) ;
TOOLTIP_TEXT ( ESFM_LONG_NAME ( ESFM_MODIN ) ) ;
ImGui : : SetCursorPos ( prevCurPos ) ;
} else {
prevCurPos = ImGui : : GetCursorPos ( ) ;
ImGui : : SetCursorPos ( ImVec2 ( textX_tl , textY ) ) ;
CENTER_TEXT ( FM_SHORT_NAME ( FM_TL ) ) ;
ImGui : : TextUnformatted ( FM_SHORT_NAME ( FM_TL ) ) ;
TOOLTIP_TEXT ( FM_NAME ( FM_TL ) ) ;
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : SetCursorPos ( prevCurPos ) ;
}
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : EndTable ( ) ;
}
ImGui : : PopStyleVar ( ) ;
2022-03-25 18:16:47 -05:00
2024-05-04 22:10:31 -05:00
if ( settings . separateFMColors ) {
popAccentColors ( ) ;
}
2022-03-25 18:16:47 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : PopID ( ) ;
}
ImGui : : EndTable ( ) ;
}
ImGui : : PopStyleVar ( ) ;
} else { // classic
int columns = 2 ;
switch ( settings . fmLayout ) {
case 1 : // 2x2
columns = 2 ;
break ;
case 2 : // 1x4
columns = 1 ;
break ;
case 3 : // 4x1
columns = opCount ;
break ;
}
if ( ImGui : : BeginTable ( " FMOperators " , columns , ImGuiTableFlags_SizingStretchSame ) ) {
for ( int i = 0 ; i < opCount ; i + + ) {
DivInstrumentFM : : Operator & op = fmOrigin . op [ ( opCount = = 4 & & ins - > type ! = DIV_INS_OPL_DRUMS & & ins - > type ! = DIV_INS_ESFM ) ? opOrder [ i ] : i ] ;
DivInstrumentESFM : : Operator & opE = ins - > esfm . op [ i ] ;
if ( ( settings . fmLayout ! = 3 & & ( ( i + 1 ) & 1 ) ) | | i = = 0 | | settings . fmLayout = = 2 ) ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : Separator ( ) ;
ImGui : : PushID ( fmt : : sprintf ( " op%d " , i ) . c_str ( ) ) ;
// push colors
if ( settings . separateFMColors ) {
bool mod = true ;
if ( ins - > type = = DIV_INS_OPL_DRUMS ) {
mod = false ;
} else if ( ins - > type = = DIV_INS_ESFM ) {
// this is the same as the KVS heuristic in platform/esfm.h
if ( opE . outLvl = = 7 ) {
mod = false ;
} else if ( opE . outLvl > 0 ) {
if ( i = = 3 ) {
mod = false ;
} else {
DivInstrumentESFM : : Operator & opENext = ins - > esfm . op [ i + 1 ] ;
if ( opENext . modIn = = 0 ) {
mod = false ;
} else if ( ( opE . outLvl - opENext . modIn ) > = 2 ) {
mod = false ;
2022-11-15 17:51:43 -05:00
}
2024-05-04 22:10:31 -05:00
}
}
} else if ( opCount = = 4 ) {
if ( ins - > type = = DIV_INS_OPL ) {
if ( opIsOutputOPL [ fmOrigin . alg & 3 ] [ i ] ) mod = false ;
} else {
if ( opIsOutput [ fmOrigin . alg & 7 ] [ i ] ) mod = false ;
}
} else {
if ( i = = 1 | | ( ins - > type = = DIV_INS_OPL & & ( fmOrigin . alg & 1 ) ) ) mod = false ;
}
if ( mod ) {
pushAccentColors (
uiColors [ GUI_COLOR_FM_PRIMARY_MOD ] ,
uiColors [ GUI_COLOR_FM_SECONDARY_MOD ] ,
uiColors [ GUI_COLOR_FM_BORDER_MOD ] ,
uiColors [ GUI_COLOR_FM_BORDER_SHADOW_MOD ]
) ;
} else {
pushAccentColors (
uiColors [ GUI_COLOR_FM_PRIMARY_CAR ] ,
uiColors [ GUI_COLOR_FM_SECONDARY_CAR ] ,
uiColors [ GUI_COLOR_FM_BORDER_CAR ] ,
uiColors [ GUI_COLOR_FM_BORDER_SHADOW_CAR ]
) ;
}
}
2022-09-21 23:25:57 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : Dummy ( ImVec2 ( dpiScale , dpiScale ) ) ;
String opNameLabel ;
OP_DRAG_POINT ;
ImGui : : SameLine ( ) ;
if ( ins - > type = = DIV_INS_OPL_DRUMS ) {
opNameLabel = fmt : : sprintf ( " %s " , oplDrumNames [ i ] ) ;
} else if ( ins - > type = = DIV_INS_OPL & & fmOrigin . opllPreset = = 16 ) {
if ( i = = 1 ) {
2024-05-26 19:31:17 -05:00
opNameLabel = _ ( " Envelope 2 (kick only) " ) ;
2024-05-04 22:10:31 -05:00
} else {
2024-05-26 19:31:17 -05:00
opNameLabel = _ ( " Envelope " ) ;
2024-05-04 22:10:31 -05:00
}
} else {
opNameLabel = fmt : : sprintf ( " OP%d " , i + 1 ) ;
}
if ( opsAreMutable ) {
pushToggleColors ( op . enable ) ;
if ( ImGui : : Button ( opNameLabel . c_str ( ) ) ) {
op . enable = ! op . enable ;
PARAMETER ;
}
popToggleColors ( ) ;
} else {
ImGui : : TextUnformatted ( opNameLabel . c_str ( ) ) ;
}
2023-10-14 17:09:18 -03:00
2024-05-04 22:10:31 -05:00
ImGui : : SameLine ( ) ;
2022-09-21 23:25:57 -05:00
2024-05-04 22:10:31 -05:00
bool amOn = op . am ;
if ( ImGui : : Checkbox ( FM_NAME ( FM_AM ) , & amOn ) ) { PARAMETER
op . am = amOn ;
}
2022-03-25 18:16:47 -05:00
2024-05-04 22:10:31 -05:00
int maxTl = 127 ;
if ( ins - > type = = DIV_INS_OPLL ) {
if ( i = = 1 ) {
maxTl = 15 ;
} else {
maxTl = 63 ;
}
}
if ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS | | ins - > type = = DIV_INS_ESFM ) {
maxTl = 63 ;
}
int maxArDr = ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) ? 31 : 15 ;
bool ssgOn = op . ssgEnv & 8 ;
bool ksrOn = op . ksr ;
bool vibOn = op . vib ;
bool susOn = op . sus ; // don't you make fun of this one
unsigned char ssgEnv = op . ssgEnv & 7 ;
if ( ins - > type ! = DIV_INS_OPL & & ins - > type ! = DIV_INS_OPL_DRUMS & & ins - > type ! = DIV_INS_OPZ & & ins - > type ! = DIV_INS_OPM & & ins - > type ! = DIV_INS_ESFM ) {
ImGui : : SameLine ( ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Checkbox ( ( ins - > type = = DIV_INS_OPLL ) ? FM_NAME ( FM_EGS ) : _ ( " SSG On " ) , & ssgOn ) ) { PARAMETER
2024-05-04 22:10:31 -05:00
op . ssgEnv = ( op . ssgEnv & 7 ) | ( ssgOn < < 3 ) ;
}
}
2022-03-25 18:16:47 -05:00
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS | | ins - > type = = DIV_INS_ESFM ) {
ImGui : : SameLine ( ) ;
if ( ImGui : : Checkbox ( FM_NAME ( FM_SUS ) , & susOn ) ) { PARAMETER
op . sus = susOn ;
}
}
2022-03-25 18:16:47 -05:00
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_OPZ ) {
ImGui : : SameLine ( ) ;
bool fixedOn = op . egt ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Checkbox ( _ ( " Fixed " ) , & fixedOn ) ) { PARAMETER
2024-05-04 22:10:31 -05:00
op . egt = fixedOn ;
}
2024-08-25 13:33:01 +03:00
bool susOn = op . sus ;
2024-09-22 03:58:17 -05:00
if ( fixedOn ) {
2024-08-25 13:33:01 +03:00
ImGui : : SameLine ( ) ;
2025-10-22 14:00:52 -05:00
pushWarningColor ( susOn & & ! e - > song . linearPitch ) ;
2024-09-22 16:56:54 -05:00
if ( ImGui : : Checkbox ( _ ( " Pitch control " ) , & susOn ) ) { PARAMETER
2024-08-25 13:33:01 +03:00
op . sus = susOn ;
2024-08-25 17:26:59 +03:00
// HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly
2025-03-10 12:35:05 -05:00
ins - > temp . vZoom [ DIV_MACRO_OP_SSG + ( i < < 5 ) ] = - 1 ;
ins - > temp . vZoom [ DIV_MACRO_OP_SUS + ( i < < 5 ) ] = - 1 ;
2024-08-25 13:33:01 +03:00
}
2024-09-22 16:56:54 -05:00
popWarningColor ( ) ;
2024-09-22 03:58:17 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2025-10-22 14:00:52 -05:00
if ( susOn & & ! e - > song . linearPitch ) {
2024-09-22 16:56:54 -05:00
ImGui : : SetTooltip ( _ ( " only works on linear pitch! go to Compatibility Flags > Pitch/Playback and set Pitch linearity to Full. " ) ) ;
} else {
ImGui : : SetTooltip ( _ ( " use op's arpeggio and pitch macros control instead of block/f-num macros " ) ) ;
}
2024-08-25 13:33:01 +03:00
}
}
2024-05-04 22:10:31 -05:00
}
2022-03-27 03:38:04 -05:00
2024-05-04 22:10:31 -05:00
//52.0 controls vert scaling; default 96
drawFMEnv ( op . tl & maxTl , op . ar & maxArDr , op . dr & maxArDr , ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS | | ins - > type = = DIV_INS_OPLL | | ins - > type = = DIV_INS_ESFM ) ? ( ( op . rr & 15 ) * 2 ) : op . d2r & 31 , op . rr & 15 , op . sl & 15 , op . sus , op . ssgEnv & 8 , fmOrigin . alg , maxTl , maxArDr , 15 , ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , 52.0 * dpiScale ) , ins - > type ) ;
//P(CWSliderScalar(FM_NAME(FM_AR),ImGuiDataType_U8,&op.ar,&_ZERO,&_THIRTY_ONE)); rightClickable
if ( ImGui : : BeginTable ( " opParams " , 2 , ImGuiTableFlags_SizingStretchProp ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthStretch , 0.0 ) ; \
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthFixed , 0.0 ) ; \
2022-03-25 18:16:47 -05:00
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_ESFM ) {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
opE . delay & = 7 ;
P ( CWSliderScalar ( " ##DELAY " , ImGuiDataType_U8 , & opE . delay , & _ZERO , & _SEVEN ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , ESFM_NAME ( ESFM_DELAY ) ) ;
}
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
op . ar & = maxArDr ;
P ( CWSliderScalar ( " ##AR " , ImGuiDataType_U8 , & op . ar , & maxArDr , & _ZERO ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_AR ) ) ;
2022-03-25 18:16:47 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
op . dr & = maxArDr ;
P ( CWSliderScalar ( " ##DR " , ImGuiDataType_U8 , & op . dr , & maxArDr , & _ZERO ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_DR ) ) ;
2023-10-14 17:09:18 -03:00
2024-05-04 22:10:31 -05:00
if ( settings . susPosition = = 0 ) {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( " ##SL " , ImGuiDataType_U8 , & op . sl , & _FIFTEEN , & _ZERO ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_SL ) ) ;
}
2023-10-14 17:09:18 -03:00
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( " ##D2R " , ImGuiDataType_U8 , & op . d2r , & _THIRTY_ONE , & _ZERO ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_D2R ) ) ;
}
2023-10-14 17:09:18 -03:00
2024-05-04 22:10:31 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( " ##RR " , ImGuiDataType_U8 , & op . rr , & _FIFTEEN , & _ZERO ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_RR ) ) ;
2023-10-14 17:09:18 -03:00
2024-07-25 19:36:40 -05:00
if ( settings . susPosition > 0 ) {
2024-05-04 22:10:31 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( " ##SL " , ImGuiDataType_U8 , & op . sl , & _FIFTEEN , & _ZERO ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_SL ) ) ;
}
2022-03-25 18:16:47 -05:00
2024-05-04 22:10:31 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
op . tl & = maxTl ;
P ( CWSliderScalar ( " ##TL " , ImGuiDataType_U8 , & op . tl , & maxTl , & _ZERO ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_TL ) ) ;
2023-10-15 11:44:12 -03:00
2024-05-04 22:10:31 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : Separator ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : Separator ( ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) {
P ( CWSliderScalar ( " ##RS " , ImGuiDataType_U8 , & op . rs , & _ZERO , & _THREE ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_RS ) ) ;
} else {
int ksl = ins - > type = = DIV_INS_OPLL ? op . ksl : kslMap [ op . ksl & 3 ] ;
if ( CWSliderInt ( " ##KSL " , & ksl , 0 , 3 ) ) {
op . ksl = ( ins - > type = = DIV_INS_OPLL ? ksl : kslMap [ ksl & 3 ] ) ;
PARAMETER ;
} rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_KSL ) ) ;
}
2022-04-12 18:26:25 -05:00
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_OPZ ) {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( FM_NAME ( FM_EGSHIFT ) , ImGuiDataType_U8 , & op . ksl , & _ZERO , & _THREE ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_EGSHIFT ) ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( FM_NAME ( FM_REV ) , ImGuiDataType_U8 , & op . dam , & _ZERO , & _SEVEN ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_REV ) ) ;
}
if ( ins - > type = = DIV_INS_OPZ ) {
if ( op . egt ) {
2024-08-25 17:26:59 +03:00
bool susOn = op . sus ;
2024-09-22 03:58:17 -05:00
if ( ! susOn ) {
2024-08-25 17:26:59 +03:00
int block = op . dt ;
int freqNum = ( op . mult < < 4 ) | ( op . dvb & 15 ) ;
2024-05-04 22:10:31 -05:00
2024-08-25 17:26:59 +03:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( FM_NAME ( FM_MULT ) , & block , 0 , 7 ) ) { PARAMETER
if ( block < 0 ) block = 0 ;
if ( block > 7 ) block = 7 ;
op . dt = block ;
} rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " Block " ) ;
2024-05-04 22:10:31 -05:00
2024-08-25 17:26:59 +03:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( FM_NAME ( FM_FINE ) , & freqNum , 0 , 255 ) ) { PARAMETER
if ( freqNum < 0 ) freqNum = 0 ;
if ( freqNum > 255 ) freqNum = 255 ;
op . mult = freqNum > > 4 ;
op . dvb = freqNum & 15 ;
} rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( _ ( " FreqNum " ) ) ;
}
2024-05-04 22:10:31 -05:00
} else {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( FM_NAME ( FM_MULT ) , ImGuiDataType_U8 , & op . mult , & _ZERO , & _FIFTEEN ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_MULT ) ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( FM_NAME ( FM_FINE ) , ImGuiDataType_U8 , & op . dvb , & _ZERO , & _FIFTEEN ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_FINE ) ) ;
}
} else {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2024-11-11 03:57:23 -05:00
pushWarningColor ( ins - > type = = DIV_INS_OPL_DRUMS & & i = = 0 ) ;
2024-05-04 22:10:31 -05:00
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( FM_NAME ( FM_MULT ) , ImGuiDataType_U8 , & op . mult , & _ZERO , & _FIFTEEN ) ) ; rightClickable
2024-11-11 03:57:23 -05:00
if ( ins - > type = = DIV_INS_OPL_DRUMS & & i = = 0 ) {
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( " %s " , _ ( " Snare's multiplier is determined by HiHat's. " ) ) ;
}
}
popWarningColor ( ) ;
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_MULT ) ) ;
}
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) {
if ( ! ( ins - > type = = DIV_INS_OPZ & & op . egt ) ) {
int detune = detuneMap [ settings . unsignedDetune ? 1 : 0 ] [ op . dt & 7 ] ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( CWSliderInt ( " ##DT " , & detune , settings . unsignedDetune ? 0 : - 3 , settings . unsignedDetune ? 7 : 4 ) ) { PARAMETER
if ( detune < - 3 ) detune = - 3 ;
if ( detune > 7 ) detune = 7 ;
op . dt = detuneUnmap [ settings . unsignedDetune ? 1 : 0 ] [ detune + 3 ] ;
} rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_DT ) ) ;
}
if ( ins - > type ! = DIV_INS_FM ) {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( " ##DT2 " , ImGuiDataType_U8 , & op . dt2 , & _ZERO , & _THREE ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_DT2 ) ) ;
}
2022-11-15 17:51:43 -05:00
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_FM ) { // OPN only
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
2024-05-26 19:31:17 -05:00
if ( CWSliderScalar ( " ##SSG " , ImGuiDataType_U8 , & ssgEnv , & _ZERO , & _SEVEN , _ ( ssgEnvTypes [ ssgEnv ] ) ) ) { PARAMETER
2024-05-04 22:10:31 -05:00
op . ssgEnv = ( op . ssgEnv & 8 ) | ( ssgEnv & 7 ) ;
} rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_SSG ) ) ;
}
}
if ( ins - > type = = DIV_INS_ESFM ) {
bool fixedOn = opE . fixed ;
if ( fixedOn ) {
int block = ( opE . ct > > 2 ) & 7 ;
int freqNum = ( ( opE . ct & 3 ) < < 8 ) | ( ( unsigned char ) opE . dt ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( ImGui : : InputInt ( " ##Block " , & block , 1 , 1 ) ) {
if ( block < 0 ) block = 0 ;
if ( block > 7 ) block = 7 ;
opE . ct = ( opE . ct & ( ~ ( 7 < < 2 ) ) ) | ( block < < 2 ) ;
2022-02-26 03:27:37 -05:00
}
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Block " ) ) ;
2024-05-04 22:10:31 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( ImGui : : InputInt ( " ##FreqNum " , & freqNum , 1 , 16 ) ) {
if ( freqNum < 0 ) freqNum = 0 ;
if ( freqNum > 1023 ) freqNum = 1023 ;
opE . dt = freqNum & 0xff ;
opE . ct = ( opE . ct & ( ~ 3 ) ) | ( freqNum > > 8 ) ;
}
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " FreqNum " ) ) ;
2024-05-04 22:10:31 -05:00
} else {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( " ##CT " , ImGuiDataType_S8 , & opE . ct , & _MINUS_TWENTY_FOUR , & _TWENTY_FOUR ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , ESFM_NAME ( ESFM_CT ) ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( " ##DT " , ImGuiDataType_S8 , & opE . dt , & _MINUS_ONE_HUNDRED_TWENTY_EIGHT , & _ONE_HUNDRED_TWENTY_SEVEN ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , ESFM_NAME ( ESFM_DT ) ) ;
}
}
if ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_ESFM ) {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( " ##WS " , ImGuiDataType_U8 , & op . ws , & _ZERO , & _SEVEN , ( ins - > type = = DIV_INS_OPZ ) ? opzWaveforms [ op . ws & 7 ] : ( settings . oplStandardWaveNames ? oplWaveformsStandard [ op . ws & 7 ] : oplWaveforms [ op . ws & 7 ] ) ) ) ; rightClickable
if ( ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS ) & & ImGui : : IsItemHovered ( ) ) {
2024-09-09 20:26:59 +09:00
ImGui : : SetTooltip ( _ ( " OPL2/3/4 only (last 4 waveforms are OPL3/4 only) " ) ) ;
2024-05-04 22:10:31 -05:00
}
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , FM_NAME ( FM_WS ) ) ;
}
if ( ins - > type = = DIV_INS_ESFM ) {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : Separator ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : Separator ( ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( " ##OUTLVL " , ImGuiDataType_U8 , & opE . outLvl , & _ZERO , & _SEVEN ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , ESFM_NAME ( ESFM_OUTLVL ) ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( " ##MODIN " , ImGuiDataType_U8 , & opE . modIn , & _ZERO , & _SEVEN ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %s " , ESFM_NAME ( ESFM_MODIN ) ) ;
}
ImGui : : EndTable ( ) ;
}
if ( ins - > type = = DIV_INS_OPLL | | ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS | | ins - > type = = DIV_INS_ESFM ) {
if ( ImGui : : Checkbox ( FM_NAME ( FM_VIB ) , & vibOn ) ) { PARAMETER
op . vib = vibOn ;
}
ImGui : : SameLine ( ) ;
if ( ImGui : : Checkbox ( FM_NAME ( FM_KSR ) , & ksrOn ) ) { PARAMETER
op . ksr = ksrOn ;
}
}
if ( ins - > type = = DIV_INS_ESFM ) {
bool dvbOn = op . dvb ;
bool damOn = op . dam ;
bool leftOn = opE . left ;
bool rightOn = opE . right ;
bool fixedOn = opE . fixed ;
if ( ImGui : : Checkbox ( FM_NAME ( FM_DVB ) , & dvbOn ) ) { PARAMETER
op . dvb = dvbOn ;
}
ImGui : : SameLine ( ) ;
if ( ImGui : : Checkbox ( FM_NAME ( FM_DAM ) , & damOn ) ) { PARAMETER
op . dam = damOn ;
}
if ( ImGui : : Checkbox ( ESFM_NAME ( ESFM_LEFT ) , & leftOn ) ) { PARAMETER
opE . left = leftOn ;
}
ImGui : : SameLine ( ) ;
if ( ImGui : : Checkbox ( ESFM_NAME ( ESFM_RIGHT ) , & rightOn ) ) { PARAMETER
opE . right = rightOn ;
}
ImGui : : SameLine ( ) ;
if ( ImGui : : Checkbox ( ESFM_NAME ( ESFM_FIXED ) , & fixedOn ) ) { PARAMETER
opE . fixed = fixedOn ;
// HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly
2025-03-10 12:35:05 -05:00
ins - > temp . vZoom [ DIV_MACRO_OP_SSG + ( i < < 5 ) ] = - 1 ;
ins - > temp . vZoom [ DIV_MACRO_OP_DT + ( i < < 5 ) ] = - 1 ;
2024-05-04 22:10:31 -05:00
}
}
if ( settings . separateFMColors ) {
popAccentColors ( ) ;
}
ImGui : : PopID ( ) ;
}
ImGui : : EndTable ( ) ;
}
}
ImGui : : EndDisabled ( ) ;
ImGui : : EndTabItem ( ) ;
}
}
2024-09-21 17:56:37 -05:00
void FurnaceGUI : : drawInsSID3 ( DivInstrument * ins ) {
2024-08-16 10:22:59 +03:00
char buffer [ 100 ] ;
char buffer2 [ 100 ] ;
2024-08-06 16:43:24 +03:00
2024-09-21 17:56:37 -05:00
if ( ImGui : : BeginTabItem ( " SID3 " ) ) {
if ( ImGui : : BeginTable ( " sid3Waves " , 2 , 0 ) ) {
2024-08-01 22:05:18 +03:00
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthFixed , 0.0f ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthFixed , 0.0f ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " Waveform " ) ) ;
ImGui : : SameLine ( ) ;
2024-09-13 23:08:25 -05:00
pushToggleColors ( ins - > sid3 . triOn ) ;
2024-08-01 22:05:18 +03:00
if ( ImGui : : Button ( _ ( " tri " ) ) ) { PARAMETER
2024-09-13 23:08:25 -05:00
ins - > sid3 . triOn = ! ins - > sid3 . triOn ;
2024-08-01 22:05:18 +03:00
}
popToggleColors ( ) ;
ImGui : : SameLine ( ) ;
2024-09-13 23:08:25 -05:00
pushToggleColors ( ins - > sid3 . sawOn ) ;
2024-08-01 22:05:18 +03:00
if ( ImGui : : Button ( _ ( " saw " ) ) ) { PARAMETER
2024-09-13 23:08:25 -05:00
ins - > sid3 . sawOn = ! ins - > sid3 . sawOn ;
2024-08-01 22:05:18 +03:00
}
popToggleColors ( ) ;
ImGui : : SameLine ( ) ;
2024-09-13 23:08:25 -05:00
pushToggleColors ( ins - > sid3 . pulseOn ) ;
2024-08-01 22:05:18 +03:00
if ( ImGui : : Button ( _ ( " pulse " ) ) ) { PARAMETER
2024-09-13 23:08:25 -05:00
ins - > sid3 . pulseOn = ! ins - > sid3 . pulseOn ;
2024-08-01 22:05:18 +03:00
}
popToggleColors ( ) ;
ImGui : : SameLine ( ) ;
2024-09-13 23:08:25 -05:00
pushToggleColors ( ins - > sid3 . noiseOn ) ;
2024-08-01 22:05:18 +03:00
if ( ImGui : : Button ( _ ( " noise " ) ) ) { PARAMETER
2024-09-13 23:08:25 -05:00
ins - > sid3 . noiseOn = ! ins - > sid3 . noiseOn ;
2024-08-01 22:05:18 +03:00
}
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " Like in SID2,specific noise LFSR feedback bits config can produce tonal waves. \n "
2024-08-17 13:49:56 +03:00
" Refer to the manual for LFSR bits macro configurations for which frequency calculation is altered \n "
" in a way that makes tonal noise stay in tune. " ) ) ;
}
2024-08-01 22:05:18 +03:00
popToggleColors ( ) ;
ImGui : : SameLine ( ) ;
P ( ImGui : : Checkbox ( _ ( " 1-bit noise " ) , & ins - > sid3 . oneBitNoise ) ) ;
ImGui : : SameLine ( ) ;
pushToggleColors ( ins - > sid3 . specialWaveOn ) ;
if ( ImGui : : Button ( _ ( " special " ) ) ) { PARAMETER
ins - > sid3 . specialWaveOn = ! ins - > sid3 . specialWaveOn ;
}
popToggleColors ( ) ;
2024-09-21 17:56:37 -05:00
P ( CWSliderScalar ( _ ( " Special wave " ) , ImGuiDataType_U8 , & ins - > sid3 . special_wave , & _ZERO , & _SID3_SPECIAL_WAVES , _ ( sid3SpecialWaveforms [ ins - > sid3 . special_wave % SID3_NUM_SPECIAL_WAVES ] ) ) ) ; rightClickable
2024-08-01 22:05:18 +03:00
2024-09-21 17:56:37 -05:00
if ( ImGui : : Checkbox ( _ ( " Wavetable channel " ) , & ins - > sid3 . doWavetable ) ) {
2024-08-09 14:30:45 +03:00
PARAMETER ;
2025-03-10 12:35:05 -05:00
ins - > temp . vZoom [ DIV_MACRO_WAVE ] = - 1 ;
2024-09-21 17:56:37 -05:00
for ( int i = 0 ; i < 256 ; i + + ) {
2024-08-09 14:30:45 +03:00
ins - > std . waveMacro . val [ i ] = 0 ;
}
}
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2024-08-09 14:30:45 +03:00
ImGui : : SetTooltip ( _ ( " Forces waveform macro to control wavetable index. " ) ) ;
}
2024-09-21 17:56:37 -05:00
bool invLeft = ins - > sid3 . phaseInv & SID3_INV_SIGNAL_LEFT ;
2024-08-11 16:47:49 +03:00
if ( ImGui : : Checkbox ( _ ( " Inv. left " ) , & invLeft ) ) { PARAMETER
ins - > sid3 . phaseInv ^ = SID3_INV_SIGNAL_LEFT ;
}
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2024-08-11 16:47:49 +03:00
ImGui : : SetTooltip ( _ ( " Invert left channel signal " ) ) ;
}
ImGui : : SameLine ( ) ;
2024-09-21 17:56:37 -05:00
bool invRight = ins - > sid3 . phaseInv & SID3_INV_SIGNAL_RIGHT ;
2024-08-11 16:47:49 +03:00
if ( ImGui : : Checkbox ( _ ( " Inv. right " ) , & invRight ) ) { PARAMETER
ins - > sid3 . phaseInv ^ = SID3_INV_SIGNAL_RIGHT ;
}
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2024-08-11 16:47:49 +03:00
ImGui : : SetTooltip ( _ ( " Invert right channel signal " ) ) ;
}
2024-08-01 22:05:18 +03:00
ImGui : : TableNextColumn ( ) ;
2024-08-10 15:32:05 +03:00
CENTER_TEXT ( _ ( " Special wave preview " ) ) ;
ImGui : : TextUnformatted ( _ ( " Special wave preview " ) ) ;
2024-09-21 17:56:37 -05:00
drawWaveformSID3 ( ins - > sid3 . special_wave , ImVec2 ( 120.0f * dpiScale , 70.0f * dpiScale ) ) ;
2024-08-01 22:05:18 +03:00
ImGui : : EndTable ( ) ;
2024-07-31 19:22:01 +03:00
}
ImVec2 sliderSize = ImVec2 ( 30.0f * dpiScale , 256.0 * dpiScale ) ;
2024-09-21 17:56:37 -05:00
if ( ImGui : : BeginTable ( " SID3EnvParams " , 6 , ImGuiTableFlags_NoHostExtendX ) ) {
2024-07-31 19:22:01 +03:00
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c3 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c4 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c5 " , ImGuiTableColumnFlags_WidthStretch ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( _ ( " A " ) ) ;
ImGui : : TextUnformatted ( _ ( " A " ) ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( _ ( " D " ) ) ;
ImGui : : TextUnformatted ( _ ( " D " ) ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( _ ( " S " ) ) ;
ImGui : : TextUnformatted ( _ ( " S " ) ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( _ ( " SR " ) ) ;
ImGui : : TextUnformatted ( _ ( " SR " ) ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( _ ( " R " ) ) ;
ImGui : : TextUnformatted ( _ ( " R " ) ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( _ ( " Envelope " ) ) ;
ImGui : : TextUnformatted ( _ ( " Envelope " ) ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2024-09-13 23:08:25 -05:00
P ( CWVSliderScalar ( " ##Attack " , sliderSize , ImGuiDataType_U8 , & ins - > sid3 . a , & _ZERO , & _TWO_HUNDRED_FIFTY_FIVE ) ) ; rightClickable
2024-07-31 19:22:01 +03:00
ImGui : : TableNextColumn ( ) ;
2024-09-13 23:08:25 -05:00
P ( CWVSliderScalar ( " ##Decay " , sliderSize , ImGuiDataType_U8 , & ins - > sid3 . d , & _ZERO , & _TWO_HUNDRED_FIFTY_FIVE ) ) ; rightClickable
2024-07-31 19:22:01 +03:00
ImGui : : TableNextColumn ( ) ;
2024-09-13 23:08:25 -05:00
P ( CWVSliderScalar ( " ##Sustain " , sliderSize , ImGuiDataType_U8 , & ins - > sid3 . s , & _ZERO , & _TWO_HUNDRED_FIFTY_FIVE ) ) ; rightClickable
2024-07-31 19:22:01 +03:00
ImGui : : TableNextColumn ( ) ;
P ( CWVSliderScalar ( " ##SustainRate " , sliderSize , ImGuiDataType_U8 , & ins - > sid3 . sr , & _ZERO , & _TWO_HUNDRED_FIFTY_FIVE ) ) ; rightClickable
ImGui : : TableNextColumn ( ) ;
2024-09-13 23:08:25 -05:00
P ( CWVSliderScalar ( " ##Release " , sliderSize , ImGuiDataType_U8 , & ins - > sid3 . r , & _ZERO , & _TWO_HUNDRED_FIFTY_FIVE ) ) ; rightClickable
2024-07-31 19:22:01 +03:00
ImGui : : TableNextColumn ( ) ;
2024-09-21 17:56:37 -05:00
// the (ins->sid3.r==15?(ins->sid3.r-1):ins->sid3.r) is used so release part never becomes horizontal (which isn't the case with SID3 envelope)
drawSID3Env ( 0 , ( ins - > sid3 . a = = 0 ? ( 255 ) : ( 256 - ins - > sid3 . a ) ) , ( ins - > sid3 . d = = 0 ? ( 255 ) : ( 256 - ins - > sid3 . d ) ) , ins - > sid3 . sr , 255 - ( ins - > sid3 . r = = 255 ? ( ins - > sid3 . r - 1 ) : ins - > sid3 . r ) , 255 - ins - > sid3 . s , 0 , 0 , 0 , 255 , 256 , 255 , ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , sliderSize . y ) , ins - > type ) ;
2024-07-31 19:22:01 +03:00
ImGui : : EndTable ( ) ;
}
2024-08-05 12:28:22 +03:00
2024-09-21 17:56:37 -05:00
if ( ! ins - > sid3 . doWavetable ) {
2024-09-13 23:08:25 -05:00
strncpy ( buffer , macroSID3WaveMixMode ( 0 , ( float ) ins - > sid3 . mixMode , NULL ) . c_str ( ) , 40 ) ;
P ( CWSliderScalar ( _ ( " Wave Mix Mode " ) , ImGuiDataType_U8 , & ins - > sid3 . mixMode , & _ZERO , & _FOUR , buffer ) ) ;
P ( CWSliderScalar ( _ ( " Duty " ) , ImGuiDataType_U16 , & ins - > sid3 . duty , & _ZERO , & _SIXTY_FIVE_THOUSAND_FIVE_HUNDRED_THIRTY_FIVE ) ) ; rightClickable
2024-08-11 21:41:48 +03:00
P ( CWSliderScalar ( _ ( " Feedback " ) , ImGuiDataType_U8 , & ins - > sid3 . feedback , & _ZERO , & _TWO_HUNDRED_FIFTY_FIVE ) ) ;
2024-09-13 23:08:25 -05:00
bool resetDuty = ins - > sid3 . resetDuty ;
2024-09-21 17:56:37 -05:00
if ( ImGui : : Checkbox ( _ ( " Reset duty on new note " ) , & resetDuty ) ) { PARAMETER
2024-09-13 23:08:25 -05:00
ins - > sid3 . resetDuty = resetDuty ;
2024-08-11 21:41:48 +03:00
}
2024-09-13 23:08:25 -05:00
if ( ImGui : : Checkbox ( _ ( " Absolute Duty Macro " ) , & ins - > sid3 . dutyIsAbs ) ) {
2025-03-10 12:35:05 -05:00
ins - > temp . vZoom [ DIV_MACRO_DUTY ] = - 1 ;
2024-08-11 21:41:48 +03:00
PARAMETER ;
}
2024-08-06 09:00:16 +03:00
}
2024-08-01 22:05:18 +03:00
2024-09-13 23:08:25 -05:00
bool ringMod = ins - > sid3 . ringMod ;
2024-08-02 11:13:04 +03:00
if ( ImGui : : Checkbox ( _ ( " Ring Modulation " ) , & ringMod ) ) { PARAMETER
2024-09-13 23:08:25 -05:00
ins - > sid3 . ringMod = ringMod ;
2024-08-02 11:13:04 +03:00
}
2024-08-04 11:32:28 +03:00
ImGui : : SameLine ( ) ;
2024-08-05 12:28:22 +03:00
strncpy ( buffer , macroSID3SourceChan ( 0 , ( float ) ins - > sid3 . ring_mod_source , NULL ) . c_str ( ) , 40 ) ;
2024-08-04 11:32:28 +03:00
P ( CWSliderScalar ( _ ( " Source channel##rmsrc " ) , ImGuiDataType_U8 , & ins - > sid3 . ring_mod_source , & _ZERO , & _SID3_NUM_CHANNELS , buffer ) ) ;
2024-08-02 11:13:04 +03:00
2024-09-13 23:08:25 -05:00
bool oscSync = ins - > sid3 . oscSync ;
2024-08-02 11:13:04 +03:00
if ( ImGui : : Checkbox ( _ ( " Oscillator Sync " ) , & oscSync ) ) { PARAMETER
2024-09-13 23:08:25 -05:00
ins - > sid3 . oscSync = oscSync ;
2024-08-02 11:13:04 +03:00
}
2024-08-04 11:32:28 +03:00
ImGui : : SameLine ( ) ;
2024-08-05 12:28:22 +03:00
strncpy ( buffer , macroSID3SourceChan ( 0 , ( float ) ins - > sid3 . sync_source , NULL ) . c_str ( ) , 40 ) ;
P ( CWSliderScalar ( _ ( " Source channel##hssrc " ) , ImGuiDataType_U8 , & ins - > sid3 . sync_source , & _ZERO , & _SID3_NUM_CHANNELS_MINUS_ONE , buffer ) ) ;
2024-08-02 11:13:04 +03:00
bool phaseMod = ins - > sid3 . phase_mod ;
if ( ImGui : : Checkbox ( _ ( " Phase modulation " ) , & phaseMod ) ) { PARAMETER
ins - > sid3 . phase_mod = phaseMod ;
}
2024-08-04 11:32:28 +03:00
ImGui : : SameLine ( ) ;
2024-08-05 12:28:22 +03:00
strncpy ( buffer , macroSID3SourceChan ( 0 , ( float ) ins - > sid3 . phase_mod_source , NULL ) . c_str ( ) , 40 ) ;
P ( CWSliderScalar ( _ ( " Source channel##pmsrc " ) , ImGuiDataType_U8 , & ins - > sid3 . phase_mod_source , & _ZERO , & _SID3_NUM_CHANNELS_MINUS_ONE , buffer ) ) ;
ImGui : : Separator ( ) ;
2024-08-11 21:41:48 +03:00
2024-09-21 17:56:37 -05:00
if ( ! ins - > sid3 . doWavetable ) {
2024-08-11 21:41:48 +03:00
bool sepNoisePitch = ins - > sid3 . separateNoisePitch ;
if ( ImGui : : Checkbox ( _ ( " Separate noise pitch " ) , & sepNoisePitch ) ) { PARAMETER
ins - > sid3 . separateNoisePitch = sepNoisePitch ;
}
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2024-08-11 21:41:48 +03:00
ImGui : : SetTooltip ( _ ( " Make noise pitch independent from other waves' pitch. \n Noise pitch will be controllable via macros. " ) ) ;
}
2024-08-05 12:28:22 +03:00
}
2024-08-04 11:32:28 +03:00
2024-09-21 17:56:37 -05:00
for ( int i = 0 ; i < SID3_NUM_FILTERS ; i + + ) {
DivInstrumentSID3 : : Filter * filt = & ins - > sid3 . filt [ i ] ;
2024-08-02 14:18:13 +03:00
2024-09-21 17:56:37 -05:00
if ( filt - > enabled ) {
2024-08-02 19:02:50 +03:00
ImGui : : Separator ( ) ;
}
2024-08-02 14:18:13 +03:00
bool enable = filt - > enabled ;
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Enable filter %d " ) , i + 1 ) ;
2024-08-02 14:18:13 +03:00
if ( ImGui : : Checkbox ( buffer , & enable ) ) { PARAMETER
filt - > enabled = enable ;
}
2024-09-21 17:56:37 -05:00
if ( filt - > enabled ) {
2024-08-02 14:18:13 +03:00
bool init = filt - > init ;
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Initialize filter %d " ) , i + 1 ) ;
2024-08-02 14:18:13 +03:00
if ( ImGui : : Checkbox ( buffer , & init ) ) { PARAMETER
filt - > init = init ;
}
ImGui : : SameLine ( ) ;
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Connect to channel input##contoinput%d " ) , i + 1 ) ;
bool toInput = filt - > mode & SID3_FILTER_CHANNEL_INPUT ;
2024-08-02 14:18:13 +03:00
if ( ImGui : : Checkbox ( buffer , & toInput ) ) { PARAMETER
2024-09-21 17:56:37 -05:00
filt - > mode ^ = SID3_FILTER_CHANNEL_INPUT ;
2024-08-02 14:18:13 +03:00
}
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Cutoff##fcut%d " ) , i + 1 ) ;
2024-08-02 14:18:13 +03:00
P ( CWSliderScalar ( buffer , ImGuiDataType_U16 , & filt - > cutoff , & _ZERO , & _SIXTY_FIVE_THOUSAND_FIVE_HUNDRED_THIRTY_FIVE ) ) ; rightClickable
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Resonance##fres%d " ) , i + 1 ) ;
2024-08-02 14:18:13 +03:00
P ( CWSliderScalar ( buffer , ImGuiDataType_U8 , & filt - > resonance , & _ZERO , & _TWO_HUNDRED_FIFTY_FIVE ) ) ; rightClickable
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Output volume##foutvol%d " ) , i + 1 ) ;
2024-08-02 14:18:13 +03:00
P ( CWSliderScalar ( buffer , ImGuiDataType_U8 , & filt - > output_volume , & _ZERO , & _TWO_HUNDRED_FIFTY_FIVE ) ) ; rightClickable
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Distortion level##fdist%d " ) , i + 1 ) ;
2024-08-07 18:36:43 +03:00
P ( CWSliderScalar ( buffer , ImGuiDataType_U8 , & filt - > distortion_level , & _ZERO , & _TWO_HUNDRED_FIFTY_FIVE ) ) ; rightClickable
2024-08-02 14:18:13 +03:00
ImGui : : AlignTextToFramePadding ( ) ;
ImGui : : Text ( _ ( " Filter Mode " ) ) ;
ImGui : : SameLine ( ) ;
2024-09-21 17:56:37 -05:00
bool lp = filt - > mode & SID3_FILTER_LP ;
2024-08-02 14:18:13 +03:00
pushToggleColors ( lp ) ;
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " low##flow%d " ) , i + 1 ) ;
2024-08-02 14:18:13 +03:00
if ( ImGui : : Button ( buffer ) ) { PARAMETER
2024-09-21 17:56:37 -05:00
filt - > mode ^ = SID3_FILTER_LP ;
2024-08-02 14:18:13 +03:00
}
popToggleColors ( ) ;
ImGui : : SameLine ( ) ;
2024-09-21 17:56:37 -05:00
bool bp = filt - > mode & SID3_FILTER_BP ;
2024-08-02 14:18:13 +03:00
pushToggleColors ( bp ) ;
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " band##fband%d " ) , i + 1 ) ;
2024-08-02 14:18:13 +03:00
if ( ImGui : : Button ( buffer ) ) { PARAMETER
2024-09-21 17:56:37 -05:00
filt - > mode ^ = SID3_FILTER_BP ;
2024-08-02 14:18:13 +03:00
}
popToggleColors ( ) ;
ImGui : : SameLine ( ) ;
2024-09-21 17:56:37 -05:00
bool hp = filt - > mode & SID3_FILTER_HP ;
2024-08-02 14:18:13 +03:00
pushToggleColors ( hp ) ;
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " high##fhigh%d " ) , i + 1 ) ;
2024-08-02 14:18:13 +03:00
if ( ImGui : : Button ( buffer ) ) { PARAMETER
2024-09-21 17:56:37 -05:00
filt - > mode ^ = SID3_FILTER_HP ;
2024-08-02 14:18:13 +03:00
}
popToggleColors ( ) ;
ImGui : : SameLine ( ) ;
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Connect to channel output##contooutput%d " ) , i + 1 ) ;
bool toOutput = filt - > mode & SID3_FILTER_OUTPUT ;
2024-08-02 14:18:13 +03:00
if ( ImGui : : Checkbox ( buffer , & toOutput ) ) { PARAMETER
2024-09-21 17:56:37 -05:00
filt - > mode ^ = SID3_FILTER_OUTPUT ;
2024-08-02 14:18:13 +03:00
}
2024-08-05 15:50:48 +03:00
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Absolute cutoff macro##abscutoff%d " ) , i + 1 ) ;
2024-08-05 15:50:48 +03:00
bool absCutoff = filt - > absoluteCutoff ;
if ( ImGui : : Checkbox ( buffer , & absCutoff ) ) { PARAMETER
2024-09-21 17:56:37 -05:00
filt - > absoluteCutoff = ! filt - > absoluteCutoff ;
2025-03-10 12:35:05 -05:00
ins - > temp . vZoom [ DIV_MACRO_OP_D2R + ( i < < 5 ) ] = - 1 ;
2024-08-05 15:50:48 +03:00
}
2024-08-16 10:22:59 +03:00
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Change cutoff with pitch##bindcutoff%d " ) , i + 1 ) ;
2024-08-16 10:22:59 +03:00
P ( ImGui : : Checkbox ( buffer , & filt - > bindCutoffToNote ) ) ;
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2024-08-16 10:22:59 +03:00
ImGui : : SetTooltip ( _ ( " Filter cutoff will change with frequency/pitch. \n See settings below. " ) ) ;
}
2024-09-21 17:56:37 -05:00
if ( filt - > bindCutoffToNote ) {
snprintf ( buffer , 100 , _ ( " Decrease cutoff when pitch increases##decreasecutoff%d " ) , i + 1 ) ;
2024-08-16 10:22:59 +03:00
P ( ImGui : : Checkbox ( buffer , & filt - > bindCutoffToNoteDir ) ) ;
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " If this is enabled,filter cutoff will decrease if you increase the pitch. \n "
" If this is disabled,filter cutoff will increase if you increase the pitch. " ) ) ;
2024-08-16 10:22:59 +03:00
}
2025-10-17 17:18:24 -05:00
snprintf ( buffer2 , 100 , _ ( " %s " ) , noteNameNormal ( filt - > bindCutoffToNoteCenter ) ) ;
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Cutoff change center note##bindcutcenternote%d " ) , i + 1 ) ;
2024-08-16 10:22:59 +03:00
P ( CWSliderScalar ( buffer , ImGuiDataType_U8 , & filt - > bindCutoffToNoteCenter , & _ZERO , & _ONE_HUNDRED_SEVENTY_NINE , buffer2 ) ) ; rightClickable
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " The center note for cutoff changes. At this note no cutoff change happens. \n As pitch goes lower or higher,cutoff changes apply. " ) ) ;
2024-08-16 10:22:59 +03:00
}
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Cutoff change strength##bindcutstrength%d " ) , i + 1 ) ;
2024-08-16 10:22:59 +03:00
P ( CWSliderScalar ( buffer , ImGuiDataType_U8 , & filt - > bindCutoffToNoteStrength , & _ZERO , & _TWO_HUNDRED_FIFTY_FIVE ) ) ; rightClickable
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2024-08-16 10:22:59 +03:00
ImGui : : SetTooltip ( _ ( " How much cutoff changes for given pitch change. " ) ) ;
}
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Scale cutoff only once on new note##bindcutnn%d " ) , i + 1 ) ;
2024-08-16 17:37:07 +03:00
P ( ImGui : : Checkbox ( buffer , & filt - > bindCutoffOnNote ) ) ;
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " Filter cutoff will be changed only once on new note. \n If this option is disabled,cutoff scaling will be applied \n every time a pitch change happens. " ) ) ;
2024-08-16 17:37:07 +03:00
}
2024-08-16 10:22:59 +03:00
}
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Change resonance with pitch##bindres%d " ) , i + 1 ) ;
2024-08-16 10:22:59 +03:00
P ( ImGui : : Checkbox ( buffer , & filt - > bindResonanceToNote ) ) ;
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2024-08-16 10:22:59 +03:00
ImGui : : SetTooltip ( _ ( " Filter resonance will change with frequency/pitch. \n See settings below. " ) ) ;
}
2024-09-21 17:56:37 -05:00
if ( filt - > bindResonanceToNote ) {
snprintf ( buffer , 100 , _ ( " Decrease resonance when pitch increases##decreaseres%d " ) , i + 1 ) ;
2024-08-16 10:22:59 +03:00
P ( ImGui : : Checkbox ( buffer , & filt - > bindResonanceToNoteDir ) ) ;
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " If this is enabled,filter resonance will decrease if you increase the pitch. \n "
" If this is disabled,filter resonance will increase if you increase the pitch. " ) ) ;
2024-08-16 10:22:59 +03:00
}
2025-10-17 17:18:24 -05:00
snprintf ( buffer2 , 100 , _ ( " %s " ) , noteNameNormal ( filt - > bindResonanceToNoteCenter ) ) ;
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Resonance change center note##bindrescenternote%d " ) , i + 1 ) ;
2024-08-16 10:22:59 +03:00
P ( CWSliderScalar ( buffer , ImGuiDataType_U8 , & filt - > bindResonanceToNoteCenter , & _ZERO , & _ONE_HUNDRED_SEVENTY_NINE , buffer2 ) ) ; rightClickable
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " The center note for resonance changes. At this note no resonance change happens. \n As pitch goes lower or higher,resonance changes apply. " ) ) ;
2024-08-16 10:22:59 +03:00
}
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Resonance change strength##bindresstrength%d " ) , i + 1 ) ;
2024-08-16 10:22:59 +03:00
P ( CWSliderScalar ( buffer , ImGuiDataType_U8 , & filt - > bindResonanceToNoteStrength , & _ZERO , & _TWO_HUNDRED_FIFTY_FIVE ) ) ; rightClickable
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2024-08-16 10:22:59 +03:00
ImGui : : SetTooltip ( _ ( " How much resonance changes for given pitch change. " ) ) ;
}
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 100 , _ ( " Scale resonance only once on new note##bindresnn%d " ) , i + 1 ) ;
2024-08-16 17:37:07 +03:00
P ( ImGui : : Checkbox ( buffer , & filt - > bindResonanceOnNote ) ) ;
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " Filter resonance will be changed only once on new note. \n If this option is disabled,resonance scaling will be applied \n every time a pitch change happens. " ) ) ;
2024-08-16 17:37:07 +03:00
}
2024-08-16 10:22:59 +03:00
}
2024-08-02 14:18:13 +03:00
}
}
2024-08-02 19:02:50 +03:00
ImGui : : Separator ( ) ;
2024-09-21 17:56:37 -05:00
if ( ImGui : : BeginTable ( " SID3filtmatrix " , 1 ) ) {
2024-08-02 19:02:50 +03:00
if ( waveGenVisible ) ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthFixed , 250.0f * dpiScale ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( _ ( " Filters connection matrix " ) ) ;
ImGui : : Text ( _ ( " Filters connection matrix " ) ) ;
2024-09-21 17:56:37 -05:00
if ( ImGui : : BeginTable ( " SID3checkboxesmatrix " , 3 + SID3_NUM_FILTERS ) ) {
2024-08-02 19:02:50 +03:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " >> " ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( _ ( " In " ) ) ;
2024-09-21 17:56:37 -05:00
for ( int i = 0 ; i < SID3_NUM_FILTERS ; i + + ) {
2024-08-02 19:02:50 +03:00
ImGui : : TableNextColumn ( ) ;
2024-09-21 17:56:37 -05:00
ImGui : : Text ( " %d " , i + 1 ) ;
2024-08-02 19:02:50 +03:00
}
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( _ ( " Out " ) ) ;
ImGui : : TableNextRow ( ) ;
2024-09-21 17:56:37 -05:00
for ( int i = 0 ; i < SID3_NUM_FILTERS ; i + + ) {
DivInstrumentSID3 : : Filter * filt = & ins - > sid3 . filt [ i ] ;
2024-08-02 19:02:50 +03:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2024-09-21 17:56:37 -05:00
ImGui : : Text ( " %d " , i + 1 ) ;
2024-08-02 19:02:50 +03:00
ImGui : : TableNextColumn ( ) ;
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 40 , " ##filtmatrixin%d " , i + 1 ) ;
bool toInput = filt - > mode & SID3_FILTER_CHANNEL_INPUT ;
2024-08-02 19:02:50 +03:00
if ( ImGui : : Checkbox ( buffer , & toInput ) ) { PARAMETER
2024-09-21 17:56:37 -05:00
filt - > mode ^ = SID3_FILTER_CHANNEL_INPUT ;
2024-08-02 19:02:50 +03:00
}
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " Feed signal from channel to filter %d input " ) , i + 1 ) ;
2024-08-02 19:02:50 +03:00
}
2024-09-21 17:56:37 -05:00
for ( int j = 0 ; j < SID3_NUM_FILTERS ; j + + ) {
2024-08-02 19:02:50 +03:00
ImGui : : TableNextColumn ( ) ;
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 40 , " ##filtmatrix%d%d " , i + 1 , j + 1 ) ;
2024-08-02 19:02:50 +03:00
2024-09-21 17:56:37 -05:00
bool enable = filt - > filter_matrix & ( 1 < < j ) ;
2024-08-02 19:02:50 +03:00
if ( ImGui : : Checkbox ( buffer , & enable ) ) { PARAMETER
2024-09-21 17:56:37 -05:00
filt - > filter_matrix ^ = ( 1 < < j ) ;
2024-08-02 19:02:50 +03:00
}
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " Feed signal from filter %d output to filter %d input " ) , j + 1 , i + 1 ) ;
2024-08-02 19:02:50 +03:00
}
}
ImGui : : TableNextColumn ( ) ;
2024-09-21 17:56:37 -05:00
snprintf ( buffer , 40 , " ##filtmatrixout%d " , i + 1 ) ;
bool toOutput = filt - > mode & SID3_FILTER_OUTPUT ;
2024-08-02 19:02:50 +03:00
if ( ImGui : : Checkbox ( buffer , & toOutput ) ) { PARAMETER
2024-09-21 17:56:37 -05:00
filt - > mode ^ = SID3_FILTER_OUTPUT ;
2024-08-02 19:02:50 +03:00
}
2024-09-21 17:56:37 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " Feed signal from filter %d output to channel output " ) , i + 1 ) ;
2024-08-02 19:02:50 +03:00
}
}
ImGui : : EndTable ( ) ;
}
ImGui : : EndTable ( ) ;
}
2024-07-31 19:22:01 +03:00
ImGui : : EndTabItem ( ) ;
}
2024-09-21 17:56:37 -05:00
if ( ! ins - > amiga . useSample ) {
2024-08-09 14:30:45 +03:00
insTabWavetable ( ins ) ;
}
2024-08-11 21:41:48 +03:00
insTabSample ( ins ) ;
2024-08-05 12:28:22 +03:00
2024-07-31 19:22:01 +03:00
std : : vector < FurnaceGUIMacroDesc > macroList ;
2024-09-21 17:56:37 -05:00
for ( int i = 0 ; i < SID3_NUM_FILTERS ; i + + ) {
snprintf ( buffer , 40 , _ ( " Filter %d macros " ) , i + 1 ) ;
2024-08-06 16:43:24 +03:00
2024-09-21 17:56:37 -05:00
if ( ImGui : : BeginTabItem ( buffer ) ) {
2024-08-06 16:43:24 +03:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Cutoff " ) , & ins - > std . opMacros [ i ] . d2rMacro , ins - > sid3 . filt [ i ] . absoluteCutoff ? 0 : - 65535 , 65535 , 160 , uiColors [ GUI_COLOR_MACRO_FILTER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Resonance " ) , & ins - > std . opMacros [ i ] . damMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_FILTER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Filter Toggle " ) , & ins - > std . opMacros [ i ] . drMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_FILTER ] , false , NULL , NULL , true ) ) ;
2024-08-10 14:21:28 +03:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Filter Mode " ) , & ins - > std . opMacros [ i ] . ksrMacro , 0 , 3 , 48 , uiColors [ GUI_COLOR_MACRO_FILTER ] , false , NULL , NULL , true , filtModeBits ) ) ;
2024-08-06 16:43:24 +03:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Distortion Level " ) , & ins - > std . opMacros [ i ] . dt2Macro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_FILTER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Output Volume " ) , & ins - > std . opMacros [ i ] . dtMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_FILTER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Channel Input Connection " ) , & ins - > std . opMacros [ i ] . dvbMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_FILTER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Channel Output Connection " ) , & ins - > std . opMacros [ i ] . egtMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_FILTER ] , false , NULL , NULL , true ) ) ;
2024-09-21 17:56:37 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Connection Matrix Row " ) , & ins - > std . opMacros [ i ] . kslMacro , 0 , SID3_NUM_FILTERS , 16 * SID3_NUM_FILTERS , uiColors [ GUI_COLOR_MACRO_FILTER ] , false , NULL , NULL , true , sid3FilterMatrixBits ) ) ;
2024-08-06 16:43:24 +03:00
2025-03-10 12:46:46 -05:00
drawMacros ( macroList , macroEditStateOP [ i ] , ins ) ;
2024-08-06 16:43:24 +03:00
ImGui : : EndTabItem ( ) ;
}
}
2024-07-31 19:22:01 +03:00
}
2024-05-04 22:10:31 -05:00
void FurnaceGUI : : drawInsEdit ( ) {
if ( nextWindow = = GUI_WINDOW_INS_EDIT ) {
insEditOpen = true ;
ImGui : : SetNextWindowFocus ( ) ;
nextWindow = GUI_WINDOW_NOTHING ;
}
if ( ! insEditOpen ) return ;
if ( mobileUI ) {
patWindowPos = ( portrait ? ImVec2 ( 0.0f , ( mobileMenuPos * - 0.65 * canvasH ) ) : ImVec2 ( ( 0.16 * canvasH ) + 0.5 * canvasW * mobileMenuPos , 0.0f ) ) ;
patWindowSize = ( portrait ? ImVec2 ( canvasW , canvasH - ( 0.16 * canvasW ) - ( pianoOpen ? ( 0.4 * canvasW ) : 0.0f ) ) : ImVec2 ( canvasW - ( 0.16 * canvasH ) , canvasH - ( pianoOpen ? ( 0.3 * canvasH ) : 0.0f ) ) ) ;
ImGui : : SetNextWindowPos ( patWindowPos ) ;
ImGui : : SetNextWindowSize ( patWindowSize ) ;
} else {
ImGui : : SetNextWindowSizeConstraints ( ImVec2 ( 440.0f * dpiScale , 400.0f * dpiScale ) , ImVec2 ( canvasW , canvasH ) ) ;
}
2024-05-27 17:53:46 -05:00
if ( ImGui : : Begin ( " Instrument Editor " , & insEditOpen , globalWinFlags | ( settings . allowEditDocking ? 0 : ImGuiWindowFlags_NoDocking ) , _ ( " Instrument Editor " ) ) ) {
2024-08-23 13:17:19 -07:00
DivInstrument * ins = NULL ;
2024-05-04 22:10:31 -05:00
if ( curIns = = - 2 ) {
ImGui : : SetCursorPosY ( ImGui : : GetCursorPosY ( ) + ( ImGui : : GetContentRegionAvail ( ) . y - ImGui : : GetFrameHeightWithSpacing ( ) + ImGui : : GetStyle ( ) . ItemSpacing . y ) * 0.5f ) ;
2024-05-26 19:31:17 -05:00
CENTER_TEXT ( _ ( " waiting... " ) ) ;
ImGui : : Text ( _ ( " waiting... " ) ) ;
2024-05-04 22:10:31 -05:00
} else if ( curIns < 0 | | curIns > = ( int ) e - > song . ins . size ( ) ) {
ImGui : : SetCursorPosY ( ImGui : : GetCursorPosY ( ) + ( ImGui : : GetContentRegionAvail ( ) . y - ImGui : : GetFrameHeightWithSpacing ( ) * ( e - > song . ins . empty ( ) ? 2.0f : 3.0f ) + ImGui : : GetStyle ( ) . ItemSpacing . y ) * 0.5f ) ;
2024-05-26 19:31:17 -05:00
CENTER_TEXT ( _ ( " no instrument selected " ) ) ;
ImGui : : Text ( _ ( " no instrument selected " ) ) ;
2024-05-04 22:10:31 -05:00
if ( ImGui : : BeginTable ( " noAssetCenter " , 3 ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthStretch , 0.5f ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthStretch , 0.5f ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : TableNextColumn ( ) ;
if ( e - > song . ins . size ( ) > 0 ) {
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : BeginCombo ( " ##InsSelect " , _ ( " select one... " ) ) ) {
2024-05-04 22:10:31 -05:00
String name ;
for ( size_t i = 0 ; i < e - > song . ins . size ( ) ; i + + ) {
name = fmt : : sprintf ( " %.2X: %s##_INSS%d " , i , e - > song . ins [ i ] - > name , i ) ;
if ( ImGui : : Selectable ( name . c_str ( ) , curIns = = ( int ) i ) ) {
2025-10-31 19:36:13 -05:00
setCurIns ( i ) ;
2024-05-04 22:10:31 -05:00
wavePreviewInit = true ;
updateFMPreview = true ;
2025-10-31 19:36:13 -05:00
ins = e - > song . ins [ curIns ] ;
2024-05-04 22:10:31 -05:00
}
}
ImGui : : EndCombo ( ) ;
}
ImGui : : AlignTextToFramePadding ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : TextUnformatted ( _ ( " or " ) ) ;
2024-05-04 22:10:31 -05:00
ImGui : : SameLine ( ) ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : Button ( _ ( " Open " ) ) ) {
2024-05-04 22:10:31 -05:00
doAction ( GUI_ACTION_INS_LIST_OPEN ) ;
}
ImGui : : SameLine ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : TextUnformatted ( _ ( " or " ) ) ;
2024-05-04 22:10:31 -05:00
ImGui : : SameLine ( ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Button ( _ ( " Create New " ) ) ) {
2024-05-04 22:10:31 -05:00
doAction ( GUI_ACTION_INS_LIST_ADD ) ;
}
ImGui : : TableNextColumn ( ) ;
ImGui : : EndTable ( ) ;
}
} else {
2024-08-23 13:17:19 -07:00
ins = e - > song . ins [ curIns ] ;
2024-05-04 22:10:31 -05:00
if ( updateFMPreview ) {
renderFMPreview ( ins ) ;
updateFMPreview = false ;
}
if ( settings . insEditColorize ) {
if ( ins - > type > = DIV_INS_MAX ) {
pushAccentColors ( uiColors [ GUI_COLOR_INSTR_UNKNOWN ] , uiColors [ GUI_COLOR_INSTR_UNKNOWN ] , uiColors [ GUI_COLOR_INSTR_UNKNOWN ] , ImVec4 ( 0.0f , 0.0f , 0.0f , 0.0f ) ) ;
} else {
pushAccentColors ( uiColors [ GUI_COLOR_INSTR_STD + ins - > type ] , uiColors [ GUI_COLOR_INSTR_STD + ins - > type ] , uiColors [ GUI_COLOR_INSTR_STD + ins - > type ] , ImVec4 ( 0.0f , 0.0f , 0.0f , 0.0f ) ) ;
}
}
if ( ImGui : : BeginTable ( " InsProp " , 3 ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthStretch ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
String insIndex = fmt : : sprintf ( " %.2X " , curIns ) ;
ImGui : : SetNextItemWidth ( 72.0f * dpiScale ) ;
if ( ImGui : : BeginCombo ( " ##InsSelect " , insIndex . c_str ( ) ) ) {
String name ;
for ( size_t i = 0 ; i < e - > song . ins . size ( ) ; i + + ) {
name = fmt : : sprintf ( " %.2X: %s##_INSS%d " , i , e - > song . ins [ i ] - > name , i ) ;
if ( ImGui : : Selectable ( name . c_str ( ) , curIns = = ( int ) i ) ) {
2025-10-31 19:36:13 -05:00
setCurIns ( i ) ;
2024-05-04 22:10:31 -05:00
ins = e - > song . ins [ curIns ] ;
wavePreviewInit = true ;
updateFMPreview = true ;
}
}
ImGui : : EndCombo ( ) ;
}
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Name " ) ) ;
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
ImGui : : PushID ( 2 + curIns ) ;
if ( ImGui : : InputText ( " ##Name " , & ins - > name ) ) {
MARK_MODIFIED ;
}
ImGui : : PopID ( ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : Button ( ICON_FA_FOLDER_OPEN " ##IELoad " ) ) {
doAction ( GUI_ACTION_INS_LIST_OPEN_REPLACE ) ;
}
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Open " ) ) ;
2024-05-04 22:10:31 -05:00
}
ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( ICON_FA_FLOPPY_O " ##IESave " ) ) {
doAction ( GUI_ACTION_INS_LIST_SAVE ) ;
}
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Save " ) ) ;
2024-05-04 22:10:31 -05:00
}
if ( ImGui : : BeginPopupContextItem ( " InsSaveFormats " , ImGuiMouseButton_Right ) ) {
2024-05-26 19:31:17 -05:00
if ( ImGui : : MenuItem ( _ ( " save as .dmp... " ) ) ) {
2024-05-04 22:10:31 -05:00
doAction ( GUI_ACTION_INS_LIST_SAVE_DMP ) ;
}
ImGui : : EndPopup ( ) ;
}
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Type " ) ) ;
2024-05-04 22:10:31 -05:00
ImGui : : TableNextColumn ( ) ;
int insType = ins - > type ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
bool warnType = true ;
for ( DivInstrumentType i : e - > getPossibleInsTypes ( ) ) {
if ( i = = insType ) {
warnType = false ;
}
}
pushWarningColor ( warnType , warnType & & failedNoteOn ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : BeginCombo ( " ##Type " , ( insType > = DIV_INS_MAX ) ? _ ( " Unknown " ) : _ ( insTypes [ insType ] [ 0 ] ) ) ) {
2024-05-04 22:10:31 -05:00
std : : vector < DivInstrumentType > insTypeList ;
if ( settings . displayAllInsTypes ) {
for ( int i = 0 ; insTypes [ i ] [ 0 ] ; i + + ) {
insTypeList . push_back ( ( DivInstrumentType ) i ) ;
}
} else {
insTypeList = e - > getPossibleInsTypes ( ) ;
}
for ( DivInstrumentType i : insTypeList ) {
if ( ImGui : : Selectable ( insTypes [ i ] [ 0 ] , insType = = i ) ) {
ins - > type = i ;
2025-07-24 03:15:50 -05:00
MARK_MODIFIED ;
2024-05-04 22:10:31 -05:00
// reset macro zoom
2025-03-10 12:35:05 -05:00
memset ( ins - > temp . vZoom , - 1 , sizeof ( ins - > temp . vZoom ) ) ;
2022-02-17 13:08:17 -05:00
}
}
2024-05-04 22:10:31 -05:00
ImGui : : EndCombo ( ) ;
} else if ( warnType ) {
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " none of the currently present chips are able to play this instrument type! " ) ) ;
2024-05-04 22:10:31 -05:00
}
}
popWarningColor ( ) ;
ImGui : : EndTable ( ) ;
}
if ( ImGui : : BeginTabBar ( " insEditTab " ) ) {
std : : vector < FurnaceGUIMacroDesc > macroList ;
2024-08-24 19:30:29 +03:00
2024-05-04 22:10:31 -05:00
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPLL | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPL_DRUMS | | ins - > type = = DIV_INS_OPM | | ins - > type = = DIV_INS_ESFM ) {
char label [ 32 ] ;
int opCount = 4 ;
if ( ins - > type = = DIV_INS_OPLL ) opCount = 2 ;
if ( ins - > type = = DIV_INS_OPL ) opCount = ( ins - > fm . ops = = 4 ) ? 4 : 2 ;
insTabFM ( ins ) ;
2023-10-17 19:24:57 -03:00
if ( ins - > type ! = DIV_INS_ESFM ) {
2024-05-26 19:31:17 -05:00
if ( ImGui : : BeginTabItem ( _ ( " FM Macros " ) ) ) {
2023-10-17 19:24:57 -03:00
if ( ins - > type = = DIV_INS_OPLL ) {
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_SUS ) , & ins - > std . algMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_FB ) , & ins - > std . fbMacro , 0 , 7 , 96 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_DC ) , & ins - > std . fmsMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_DM ) , & ins - > std . amsMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
} else {
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_ALG ) , & ins - > std . algMacro , 0 , 7 , 96 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_FB ) , & ins - > std . fbMacro , 0 , 7 , 96 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
if ( ins - > type ! = DIV_INS_OPL & & ins - > type ! = DIV_INS_OPL_DRUMS ) {
if ( ins - > type = = DIV_INS_OPZ ) {
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_FMS ) , & ins - > std . fmsMacro , 0 , 7 , 96 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_AMS ) , & ins - > std . amsMacro , 0 , 3 , 48 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2025-03-23 04:22:43 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_FMS2 ) , & ins - > std . ex9Macro , 0 , 7 , 96 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_AMS2 ) , & ins - > std . ex10Macro , 0 , 3 , 48 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2023-10-17 19:24:57 -03:00
} else {
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_FMS ) , & ins - > std . fmsMacro , 0 , 7 , 96 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_AMS ) , & ins - > std . amsMacro , 0 , 3 , 48 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
}
2022-04-10 14:01:55 +09:00
}
2022-03-16 02:01:44 -05:00
}
2023-10-17 19:24:57 -03:00
if ( ins - > type = = DIV_INS_FM ) {
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " LFO Speed " ) , & ins - > std . ex3Macro , 0 , 8 , 96 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2023-10-17 19:24:57 -03:00
}
if ( ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) {
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " AM Depth " ) , & ins - > std . ex1Macro , 0 , 127 , 128 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " PM Depth " ) , & ins - > std . ex2Macro , 0 , 127 , 128 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " LFO Speed " ) , & ins - > std . ex3Macro , 0 , 255 , 128 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " LFO Shape " ) , & ins - > std . waveMacro , 0 , 3 , 48 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , macroLFOWaves ) ) ;
2023-10-17 19:24:57 -03:00
}
if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPM ) {
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " OpMask " ) , & ins - > std . ex4Macro , 0 , 4 , 128 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , fmOperatorBits ) ) ;
2023-10-17 19:24:57 -03:00
} else if ( ins - > type = = DIV_INS_OPZ ) {
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " AM Depth 2 " ) , & ins - > std . ex5Macro , 0 , 127 , 128 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " PM Depth 2 " ) , & ins - > std . ex6Macro , 0 , 127 , 128 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " LFO2 Speed " ) , & ins - > std . ex7Macro , 0 , 255 , 128 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " LFO2 Shape " ) , & ins - > std . ex8Macro , 0 , 3 , 48 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , macroLFOWaves ) ) ;
2023-10-17 19:24:57 -03:00
}
2025-03-10 12:46:46 -05:00
drawMacros ( macroList , macroEditStateFM , ins ) ;
2023-10-17 19:24:57 -03:00
ImGui : : EndTabItem ( ) ;
2022-02-28 18:16:05 -05:00
}
2022-02-17 13:08:17 -05:00
}
2022-02-28 14:13:14 -05:00
for ( int i = 0 ; i < opCount ; i + + ) {
2022-05-30 18:37:07 -05:00
if ( ins - > type = = DIV_INS_OPL_DRUMS ) {
2022-05-31 17:44:52 -05:00
if ( i > 0 ) break ;
2024-05-26 19:31:17 -05:00
snprintf ( label , 31 , _ ( " Operator Macros " ) ) ;
2022-05-30 18:37:07 -05:00
} else {
2024-05-26 19:31:17 -05:00
snprintf ( label , 31 , _ ( " OP%d Macros " ) , i + 1 ) ;
2022-05-30 18:37:07 -05:00
}
2022-02-17 13:08:17 -05:00
if ( ImGui : : BeginTabItem ( label ) ) {
ImGui : : PushID ( i ) ;
2023-10-18 17:01:46 -03:00
int ordi = ( opCount = = 4 & & ins - > type ! = DIV_INS_ESFM ) ? orderedOps [ i ] : i ;
2022-02-28 14:13:14 -05:00
int maxTl = 127 ;
if ( ins - > type = = DIV_INS_OPLL ) {
if ( i = = 1 ) {
maxTl = 15 ;
} else {
maxTl = 63 ;
}
}
2023-10-17 19:24:57 -03:00
if ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS | | ins - > type = = DIV_INS_ESFM ) {
2022-03-16 02:01:44 -05:00
maxTl = 63 ;
}
2022-09-24 00:57:53 -05:00
int maxArDr = ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPZ | | ins - > type = = DIV_INS_OPM ) ? 31 : 15 ;
2022-02-28 14:13:14 -05:00
2022-05-30 18:37:07 -05:00
if ( ins - > type = = DIV_INS_OPL | | ins - > type = = DIV_INS_OPL_DRUMS ) {
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_TL ) , & ins - > std . opMacros [ ordi ] . tlMacro , 0 , maxTl , 128 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_AR ) , & ins - > std . opMacros [ ordi ] . arMacro , 0 , maxArDr , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_DR ) , & ins - > std . opMacros [ ordi ] . drMacro , 0 , maxArDr , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_SL ) , & ins - > std . opMacros [ ordi ] . slMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_RR ) , & ins - > std . opMacros [ ordi ] . rrMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
2022-05-06 18:01:12 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_KSL ) , & ins - > std . opMacros [ ordi ] . kslMacro , 0 , 3 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_MULT ) , & ins - > std . opMacros [ ordi ] . multMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_WS ) , & ins - > std . opMacros [ ordi ] . wsMacro , 0 , 7 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2022-09-25 18:32:34 +09:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_AM ) , & ins - > std . opMacros [ ordi ] . amMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_VIB ) , & ins - > std . opMacros [ ordi ] . vibMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_KSR ) , & ins - > std . opMacros [ ordi ] . ksrMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_SUS ) , & ins - > std . opMacros [ ordi ] . susMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2022-03-16 02:01:44 -05:00
} else if ( ins - > type = = DIV_INS_OPLL ) {
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_TL ) , & ins - > std . opMacros [ ordi ] . tlMacro , 0 , maxTl , 128 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_AR ) , & ins - > std . opMacros [ ordi ] . arMacro , 0 , maxArDr , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_DR ) , & ins - > std . opMacros [ ordi ] . drMacro , 0 , maxArDr , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_SL ) , & ins - > std . opMacros [ ordi ] . slMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_RR ) , & ins - > std . opMacros [ ordi ] . rrMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
2022-05-06 18:01:12 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_KSL ) , & ins - > std . opMacros [ ordi ] . kslMacro , 0 , 3 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_MULT ) , & ins - > std . opMacros [ ordi ] . multMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2022-09-25 18:32:34 +09:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_AM ) , & ins - > std . opMacros [ ordi ] . amMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_VIB ) , & ins - > std . opMacros [ ordi ] . vibMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_KSR ) , & ins - > std . opMacros [ ordi ] . ksrMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_EGS ) , & ins - > std . opMacros [ ordi ] . egtMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2023-10-17 19:24:57 -03:00
} else if ( ins - > type = = DIV_INS_ESFM ) {
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_TL ) , & ins - > std . opMacros [ ordi ] . tlMacro , 0 , maxTl , 128 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
2024-08-25 13:33:01 +03:00
if ( ins - > esfm . op [ ordi ] . fixed ) {
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Block " ) , & ins - > std . opMacros [ ordi ] . ssgMacro , 0 , 7 , 64 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " FreqNum " ) , & ins - > std . opMacros [ ordi ] . dtMacro , 0 , 1023 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] ) ) ;
} else {
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Op. Arpeggio " ) , & ins - > std . opMacros [ ordi ] . ssgMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . opMacros [ ordi ] . ssgMacro . val , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Op. Pitch " ) , & ins - > std . opMacros [ ordi ] . dtMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode , NULL , false , NULL , false , NULL , false , true ) ) ;
}
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( ESFM_NAME ( ESFM_DELAY ) , & ins - > std . opMacros [ ordi ] . dt2Macro , 0 , 7 , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_AR ) , & ins - > std . opMacros [ ordi ] . arMacro , 0 , maxArDr , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_DR ) , & ins - > std . opMacros [ ordi ] . drMacro , 0 , maxArDr , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_SL ) , & ins - > std . opMacros [ ordi ] . slMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_RR ) , & ins - > std . opMacros [ ordi ] . rrMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
2023-10-17 19:24:57 -03:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_KSL ) , & ins - > std . opMacros [ ordi ] . kslMacro , 0 , 3 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_MULT ) , & ins - > std . opMacros [ ordi ] . multMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_WS ) , & ins - > std . opMacros [ ordi ] . wsMacro , 0 , 7 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( ESFM_NAME ( ESFM_OUTLVL ) , & ins - > std . opMacros [ ordi ] . egtMacro , 0 , 7 , 64 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( ESFM_NAME ( ESFM_MODIN ) , & ins - > std . opMacros [ ordi ] . d2rMacro , 0 , 7 , 64 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
2023-10-17 19:24:57 -03:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_AM ) , & ins - > std . opMacros [ ordi ] . amMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_VIB ) , & ins - > std . opMacros [ ordi ] . vibMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_DAM ) , & ins - > std . opMacros [ ordi ] . damMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_DVB ) , & ins - > std . opMacros [ ordi ] . dvbMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_KSR ) , & ins - > std . opMacros [ ordi ] . ksrMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_SUS ) , & ins - > std . opMacros [ ordi ] . susMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Op. Panning " ) , & ins - > std . opMacros [ ordi ] . rsMacro , 0 , 2 , 40 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , panBits ) ) ;
2024-09-22 03:58:17 -05:00
} else if ( ins - > type = = DIV_INS_FM | | ins - > type = = DIV_INS_OPM ) {
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_TL ) , & ins - > std . opMacros [ ordi ] . tlMacro , 0 , maxTl , 128 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_AR ) , & ins - > std . opMacros [ ordi ] . arMacro , 0 , maxArDr , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_DR ) , & ins - > std . opMacros [ ordi ] . drMacro , 0 , maxArDr , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_D2R ) , & ins - > std . opMacros [ ordi ] . d2rMacro , 0 , 31 , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_RR ) , & ins - > std . opMacros [ ordi ] . rrMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_SL ) , & ins - > std . opMacros [ ordi ] . slMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
2022-05-06 18:01:12 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_RS ) , & ins - > std . opMacros [ ordi ] . rsMacro , 0 , 3 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_MULT ) , & ins - > std . opMacros [ ordi ] . multMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_DT ) , & ins - > std . opMacros [ ordi ] . dtMacro , 0 , 7 , 64 , uiColors [ GUI_COLOR_MACRO_PITCH ] ) ) ;
2024-08-25 13:33:01 +03:00
if ( ins - > type = = DIV_INS_OPM ) {
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_DT2 ) , & ins - > std . opMacros [ ordi ] . dt2Macro , 0 , 3 , 32 , uiColors [ GUI_COLOR_MACRO_PITCH ] ) ) ;
2022-09-24 01:33:36 -05:00
}
2022-05-06 18:01:12 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_AM ) , & ins - > std . opMacros [ ordi ] . amMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
if ( ins - > type = = DIV_INS_FM ) {
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_SSG ) , & ins - > std . opMacros [ ordi ] . ssgMacro , 0 , 4 , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] , false , NULL , NULL , true , ssgEnvBits ) ) ;
2022-05-06 18:01:12 -05:00
}
2024-09-22 03:58:17 -05:00
} else if ( ins - > type = = DIV_INS_OPZ ) {
2024-08-25 13:33:01 +03:00
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_TL ) , & ins - > std . opMacros [ ordi ] . tlMacro , 0 , maxTl , 128 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
2024-09-22 03:58:17 -05:00
if ( ins - > fm . op [ ordi ] . egt ) {
2024-08-25 13:33:01 +03:00
if ( ! ins - > fm . op [ ordi ] . sus ) {
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Block " ) , & ins - > std . opMacros [ ordi ] . ssgMacro , 0 , 7 , 64 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " FreqNum " ) , & ins - > std . opMacros [ ordi ] . susMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] ) ) ;
} else {
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Op. Arpeggio " ) , & ins - > std . opMacros [ ordi ] . ssgMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . opMacros [ ordi ] . ssgMacro . val , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Op. Pitch " ) , & ins - > std . opMacros [ ordi ] . susMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode , NULL , false , NULL , false , NULL , false , true ) ) ;
}
}
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_AR ) , & ins - > std . opMacros [ ordi ] . arMacro , 0 , maxArDr , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_DR ) , & ins - > std . opMacros [ ordi ] . drMacro , 0 , maxArDr , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_D2R ) , & ins - > std . opMacros [ ordi ] . d2rMacro , 0 , 31 , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_RR ) , & ins - > std . opMacros [ ordi ] . rrMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_SL ) , & ins - > std . opMacros [ ordi ] . slMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_RS ) , & ins - > std . opMacros [ ordi ] . rsMacro , 0 , 3 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_MULT ) , & ins - > std . opMacros [ ordi ] . multMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_DT ) , & ins - > std . opMacros [ ordi ] . dtMacro , 0 , 7 , 64 , uiColors [ GUI_COLOR_MACRO_PITCH ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_DT2 ) , & ins - > std . opMacros [ ordi ] . dt2Macro , 0 , 3 , 32 , uiColors [ GUI_COLOR_MACRO_PITCH ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( FM_NAME ( FM_AM ) , & ins - > std . opMacros [ ordi ] . amMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2022-02-28 18:16:05 -05:00
}
2025-03-10 12:46:46 -05:00
drawMacros ( macroList , macroEditStateOP [ ordi ] , ins ) ;
2022-02-17 13:08:17 -05:00
ImGui : : PopID ( ) ;
ImGui : : EndTabItem ( ) ;
}
}
}
if ( ins - > type = = DIV_INS_GB ) if ( ImGui : : BeginTabItem ( " Game Boy " ) ) {
2024-05-26 19:31:17 -05:00
P ( ImGui : : Checkbox ( _ ( " Use software envelope " ) , & ins - > gb . softEnv ) ) ;
P ( ImGui : : Checkbox ( _ ( " Initialize envelope on every note " ) , & ins - > gb . alwaysInit ) ) ;
P ( ImGui : : Checkbox ( _ ( " Double wave length (GBA only) " ) , & ins - > gb . doubleWave ) ) ;
2022-02-17 13:08:17 -05:00
2022-08-10 01:55:44 -05:00
ImGui : : BeginDisabled ( ins - > gb . softEnv ) ;
2022-08-17 18:29:40 -05:00
if ( ImGui : : BeginTable ( " GBParams " , 2 ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthStretch , 0.6f ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch , 0.4f ) ;
2022-02-17 13:08:17 -05:00
2022-08-17 18:29:40 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : BeginTable ( " GBParamsI " , 2 ) ) {
ImGui : : TableSetupColumn ( " ci0 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " ci1 " , ImGuiTableColumnFlags_WidthStretch ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Volume " ) ) ;
2022-08-17 18:29:40 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( " ##GBVolume " , ImGuiDataType_U8 , & ins - > gb . envVol , & _ZERO , & _FIFTEEN ) ) ; rightClickable
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Length " ) ) ;
2022-08-17 18:29:40 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
P ( CWSliderScalar ( " ##GBEnvLen " , ImGuiDataType_U8 , & ins - > gb . envLen , & _ZERO , & _SEVEN ) ) ; rightClickable
2022-04-16 23:58:29 -05:00
2022-08-17 18:29:40 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Sound Length " ) ) ;
2022-08-17 18:29:40 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
2024-05-26 19:31:17 -05:00
P ( CWSliderScalar ( " ##GBSoundLen " , ImGuiDataType_U8 , & ins - > gb . soundLen , & _ZERO , & _SIXTY_FOUR , ins - > gb . soundLen > 63 ? _ ( " Infinity " ) : " %d " ) ) ; rightClickable
2022-04-16 23:58:29 -05:00
2022-08-17 18:29:40 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Direction " ) ) ;
2022-08-17 18:29:40 -05:00
ImGui : : TableNextColumn ( ) ;
bool goesUp = ins - > gb . envDir ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Up " ) , goesUp ) ) { PARAMETER
2022-08-17 18:29:40 -05:00
goesUp = true ;
ins - > gb . envDir = goesUp ;
}
ImGui : : SameLine ( ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Down " ) , ! goesUp ) ) { PARAMETER
2022-08-17 18:29:40 -05:00
goesUp = false ;
ins - > gb . envDir = goesUp ;
}
ImGui : : EndTable ( ) ;
}
ImGui : : TableNextColumn ( ) ;
drawGBEnv ( ins - > gb . envVol , ins - > gb . envLen , ins - > gb . soundLen , ins - > gb . envDir , ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , 100.0f * dpiScale ) ) ;
ImGui : : EndTable ( ) ;
2022-02-17 13:08:17 -05:00
}
2022-04-16 23:58:29 -05:00
2025-08-10 04:53:08 -05:00
if ( ImGui : : BeginChild ( " HWSeq " , ImGui : : GetContentRegionAvail ( ) , ImGuiChildFlags_Border , ImGuiWindowFlags_MenuBar ) ) {
2022-08-07 06:06:14 -05:00
ImGui : : BeginMenuBar ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Hardware Sequence " ) ) ;
2022-08-07 06:06:14 -05:00
ImGui : : EndMenuBar ( ) ;
2022-08-10 14:16:26 -05:00
if ( ins - > gb . hwSeqLen > 0 ) if ( ImGui : : BeginTable ( " HWSeqList " , 3 ) ) {
2022-08-07 06:06:14 -05:00
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch ) ;
2022-08-10 14:16:26 -05:00
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthFixed ) ;
2022-08-07 06:06:14 -05:00
int curFrame = 0 ;
ImGui : : TableNextRow ( ImGuiTableRowFlags_Headers ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Tick " ) ) ;
2022-08-07 06:06:14 -05:00
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Command " ) ) ;
2022-08-10 14:16:26 -05:00
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Move/Remove " ) ) ;
2022-08-07 06:06:14 -05:00
for ( int i = 0 ; i < ins - > gb . hwSeqLen ; i + + ) {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %d (#%d) " , curFrame , i ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : PushID ( i ) ;
if ( ins - > gb . hwSeq [ i ] . cmd > = DivInstrumentGB : : DIV_GB_HWCMD_MAX ) {
ins - > gb . hwSeq [ i ] . cmd = 0 ;
}
int cmd = ins - > gb . hwSeq [ i ] . cmd ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
2024-05-26 23:30:33 -05:00
if ( ImGui : : Combo ( " ##HWSeqCmd " , & cmd , LocalizedComboGetter , gbHWSeqCmdTypes , DivInstrumentGB : : DIV_GB_HWCMD_MAX ) ) {
2022-08-07 06:06:14 -05:00
if ( ins - > gb . hwSeq [ i ] . cmd ! = cmd ) {
ins - > gb . hwSeq [ i ] . cmd = cmd ;
ins - > gb . hwSeq [ i ] . data = 0 ;
}
}
bool somethingChanged = false ;
switch ( ins - > gb . hwSeq [ i ] . cmd ) {
case DivInstrumentGB : : DIV_GB_HWCMD_ENVELOPE : {
int hwsVol = ( ins - > gb . hwSeq [ i ] . data & 0xf0 ) > > 4 ;
bool hwsDir = ins - > gb . hwSeq [ i ] . data & 8 ;
int hwsLen = ins - > gb . hwSeq [ i ] . data & 7 ;
int hwsSoundLen = ins - > gb . hwSeq [ i ] . data > > 8 ;
2024-05-26 19:31:17 -05:00
if ( CWSliderInt ( _ ( " Volume " ) , & hwsVol , 0 , 15 ) ) {
2022-08-07 06:06:14 -05:00
somethingChanged = true ;
}
2024-05-26 19:31:17 -05:00
if ( CWSliderInt ( _ ( " Env Length " ) , & hwsLen , 0 , 7 ) ) {
2022-08-07 06:06:14 -05:00
somethingChanged = true ;
}
2024-05-26 19:31:17 -05:00
if ( CWSliderInt ( _ ( " Sound Length " ) , & hwsSoundLen , 0 , 64 , hwsSoundLen > 63 ? _ ( " Infinity " ) : " %d " ) ) {
2022-08-07 06:06:14 -05:00
somethingChanged = true ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Up " ) , hwsDir ) ) { PARAMETER
2022-08-07 06:06:14 -05:00
hwsDir = true ;
somethingChanged = true ;
}
ImGui : : SameLine ( ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Down " ) , ! hwsDir ) ) { PARAMETER
2022-08-07 06:06:14 -05:00
hwsDir = false ;
somethingChanged = true ;
}
if ( somethingChanged ) {
ins - > gb . hwSeq [ i ] . data = ( hwsLen & 7 ) | ( hwsDir ? 8 : 0 ) | ( hwsVol < < 4 ) | ( hwsSoundLen < < 8 ) ;
PARAMETER ;
}
break ;
}
case DivInstrumentGB : : DIV_GB_HWCMD_SWEEP : {
int hwsShift = ins - > gb . hwSeq [ i ] . data & 7 ;
int hwsSpeed = ( ins - > gb . hwSeq [ i ] . data & 0x70 ) > > 4 ;
bool hwsDir = ins - > gb . hwSeq [ i ] . data & 8 ;
2024-05-26 19:31:17 -05:00
if ( CWSliderInt ( _ ( " Shift " ) , & hwsShift , 0 , 7 ) ) {
2022-08-07 06:06:14 -05:00
somethingChanged = true ;
}
2024-05-26 19:31:17 -05:00
if ( CWSliderInt ( _ ( " Speed " ) , & hwsSpeed , 0 , 7 ) ) {
2022-08-07 06:06:14 -05:00
somethingChanged = true ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Up " ) , ! hwsDir ) ) { PARAMETER
2022-08-10 01:55:44 -05:00
hwsDir = false ;
2022-08-07 06:06:14 -05:00
somethingChanged = true ;
}
ImGui : : SameLine ( ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Down " ) , hwsDir ) ) { PARAMETER
2022-08-10 01:55:44 -05:00
hwsDir = true ;
2022-08-07 06:06:14 -05:00
somethingChanged = true ;
}
if ( somethingChanged ) {
ins - > gb . hwSeq [ i ] . data = ( hwsShift & 7 ) | ( hwsDir ? 8 : 0 ) | ( hwsSpeed < < 4 ) ;
PARAMETER ;
}
break ;
}
case DivInstrumentGB : : DIV_GB_HWCMD_WAIT : {
int len = ins - > gb . hwSeq [ i ] . data + 1 ;
curFrame + = ins - > gb . hwSeq [ i ] . data + 1 ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputInt ( _ ( " Ticks " ) , & len , 1 , 4 ) ) {
2022-08-07 06:06:14 -05:00
if ( len < 1 ) len = 1 ;
if ( len > 255 ) len = 256 ;
somethingChanged = true ;
}
if ( somethingChanged ) {
ins - > gb . hwSeq [ i ] . data = len - 1 ;
PARAMETER ;
}
break ;
}
case DivInstrumentGB : : DIV_GB_HWCMD_WAIT_REL :
curFrame + + ;
break ;
case DivInstrumentGB : : DIV_GB_HWCMD_LOOP :
case DivInstrumentGB : : DIV_GB_HWCMD_LOOP_REL : {
int pos = ins - > gb . hwSeq [ i ] . data ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputInt ( _ ( " Position " ) , & pos , 1 , 1 ) ) {
2022-08-07 06:06:14 -05:00
if ( pos < 0 ) pos = 0 ;
if ( pos > ( ins - > gb . hwSeqLen - 1 ) ) pos = ( ins - > gb . hwSeqLen - 1 ) ;
somethingChanged = true ;
}
if ( somethingChanged ) {
ins - > gb . hwSeq [ i ] . data = pos ;
PARAMETER ;
}
break ;
}
default :
break ;
}
ImGui : : PopID ( ) ;
2022-08-10 14:16:26 -05:00
ImGui : : TableNextColumn ( ) ;
ImGui : : PushID ( i + 512 ) ;
if ( ImGui : : Button ( ICON_FA_CHEVRON_UP " ##HWCmdUp " ) ) {
if ( i > 0 ) {
e - > lockEngine ( [ ins , i ] ( ) {
ins - > gb . hwSeq [ i - 1 ] . cmd ^ = ins - > gb . hwSeq [ i ] . cmd ;
ins - > gb . hwSeq [ i ] . cmd ^ = ins - > gb . hwSeq [ i - 1 ] . cmd ;
ins - > gb . hwSeq [ i - 1 ] . cmd ^ = ins - > gb . hwSeq [ i ] . cmd ;
ins - > gb . hwSeq [ i - 1 ] . data ^ = ins - > gb . hwSeq [ i ] . data ;
ins - > gb . hwSeq [ i ] . data ^ = ins - > gb . hwSeq [ i - 1 ] . data ;
ins - > gb . hwSeq [ i - 1 ] . data ^ = ins - > gb . hwSeq [ i ] . data ;
} ) ;
}
MARK_MODIFIED ;
}
ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( ICON_FA_CHEVRON_DOWN " ##HWCmdDown " ) ) {
if ( i < ins - > gb . hwSeqLen - 1 ) {
e - > lockEngine ( [ ins , i ] ( ) {
2022-08-17 18:37:16 -05:00
ins - > gb . hwSeq [ i + 1 ] . cmd ^ = ins - > gb . hwSeq [ i ] . cmd ;
ins - > gb . hwSeq [ i ] . cmd ^ = ins - > gb . hwSeq [ i + 1 ] . cmd ;
ins - > gb . hwSeq [ i + 1 ] . cmd ^ = ins - > gb . hwSeq [ i ] . cmd ;
2022-08-10 14:16:26 -05:00
2022-08-17 18:37:16 -05:00
ins - > gb . hwSeq [ i + 1 ] . data ^ = ins - > gb . hwSeq [ i ] . data ;
ins - > gb . hwSeq [ i ] . data ^ = ins - > gb . hwSeq [ i + 1 ] . data ;
ins - > gb . hwSeq [ i + 1 ] . data ^ = ins - > gb . hwSeq [ i ] . data ;
2022-08-10 14:16:26 -05:00
} ) ;
}
MARK_MODIFIED ;
}
ImGui : : SameLine ( ) ;
2023-08-26 16:09:27 +04:00
pushDestColor ( ) ;
2023-08-27 10:18:39 +04:00
if ( ImGui : : Button ( ICON_FA_TIMES " ##HWCmdDel " ) ) {
2022-08-10 14:16:26 -05:00
for ( int j = i ; j < ins - > gb . hwSeqLen - 1 ; j + + ) {
ins - > gb . hwSeq [ j ] . cmd = ins - > gb . hwSeq [ j + 1 ] . cmd ;
ins - > gb . hwSeq [ j ] . data = ins - > gb . hwSeq [ j + 1 ] . data ;
}
ins - > gb . hwSeqLen - - ;
}
2023-08-26 16:09:27 +04:00
popDestColor ( ) ;
2022-08-10 14:16:26 -05:00
ImGui : : PopID ( ) ;
2022-08-07 06:06:14 -05:00
}
ImGui : : EndTable ( ) ;
}
if ( ImGui : : Button ( ICON_FA_PLUS " ##HWCmdAdd " ) ) {
if ( ins - > gb . hwSeqLen < 255 ) {
ins - > gb . hwSeq [ ins - > gb . hwSeqLen ] . cmd = 0 ;
ins - > gb . hwSeq [ ins - > gb . hwSeqLen ] . data = 0 ;
ins - > gb . hwSeqLen + + ;
}
}
}
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
ImGui : : EndChild ( ) ;
ImGui : : EndDisabled ( ) ;
2022-02-17 13:08:17 -05:00
ImGui : : EndTabItem ( ) ;
}
2024-04-21 12:38:59 -05:00
if ( ins - > type = = DIV_INS_C64 | | ins - > type = = DIV_INS_SID2 ) if ( ImGui : : BeginTabItem ( ( ins - > type = = DIV_INS_SID2 ) ? " SID2 " : " C64 " ) ) {
2023-08-06 22:47:17 -07:00
ImGui : : AlignTextToFramePadding ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Waveform " ) ) ;
2022-02-17 13:08:17 -05:00
ImGui : : SameLine ( ) ;
2022-09-10 23:50:53 -05:00
pushToggleColors ( ins - > c64 . triOn ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Button ( _ ( " tri " ) ) ) { PARAMETER
2022-02-17 13:08:17 -05:00
ins - > c64 . triOn = ! ins - > c64 . triOn ;
}
2022-09-10 23:50:53 -05:00
popToggleColors ( ) ;
2022-02-17 13:08:17 -05:00
ImGui : : SameLine ( ) ;
2022-09-10 23:50:53 -05:00
pushToggleColors ( ins - > c64 . sawOn ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Button ( _ ( " saw " ) ) ) { PARAMETER
2022-02-17 13:08:17 -05:00
ins - > c64 . sawOn = ! ins - > c64 . sawOn ;
}
2022-09-10 23:50:53 -05:00
popToggleColors ( ) ;
2022-02-17 13:08:17 -05:00
ImGui : : SameLine ( ) ;
2022-09-10 23:50:53 -05:00
pushToggleColors ( ins - > c64 . pulseOn ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Button ( _ ( " pulse " ) ) ) { PARAMETER
2022-02-17 13:08:17 -05:00
ins - > c64 . pulseOn = ! ins - > c64 . pulseOn ;
}
2022-09-10 23:50:53 -05:00
popToggleColors ( ) ;
2022-02-17 13:08:17 -05:00
ImGui : : SameLine ( ) ;
2022-09-10 23:50:53 -05:00
pushToggleColors ( ins - > c64 . noiseOn ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Button ( _ ( " noise " ) ) ) { PARAMETER
2022-02-17 13:08:17 -05:00
ins - > c64 . noiseOn = ! ins - > c64 . noiseOn ;
}
2022-09-10 23:50:53 -05:00
popToggleColors ( ) ;
2022-02-17 13:08:17 -05:00
2022-04-17 02:51:03 -05:00
ImVec2 sliderSize = ImVec2 ( 20.0f * dpiScale , 128.0 * dpiScale ) ;
2024-04-25 13:02:40 -05:00
if ( ImGui : : BeginTable ( " C64EnvParams " , 5 , ImGuiTableFlags_NoHostExtendX ) ) {
2022-04-17 02:51:03 -05:00
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c3 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c4 " , ImGuiTableColumnFlags_WidthStretch ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( " A " ) ;
ImGui : : TextUnformatted ( " A " ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( " D " ) ;
ImGui : : TextUnformatted ( " D " ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( " S " ) ;
ImGui : : TextUnformatted ( " S " ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( " R " ) ;
ImGui : : TextUnformatted ( " R " ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
CENTER_TEXT ( _ ( " Envelope " ) ) ;
ImGui : : TextUnformatted ( _ ( " Envelope " ) ) ;
2022-04-17 02:51:03 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2023-04-20 04:01:00 -05:00
P ( CWVSliderScalar ( " ##Attack " , sliderSize , ImGuiDataType_U8 , & ins - > c64 . a , & _ZERO , & _FIFTEEN ) ) ; rightClickable
2022-04-17 02:51:03 -05:00
ImGui : : TableNextColumn ( ) ;
2023-04-20 04:01:00 -05:00
P ( CWVSliderScalar ( " ##Decay " , sliderSize , ImGuiDataType_U8 , & ins - > c64 . d , & _ZERO , & _FIFTEEN ) ) ; rightClickable
2022-04-17 02:51:03 -05:00
ImGui : : TableNextColumn ( ) ;
2023-04-20 04:01:00 -05:00
P ( CWVSliderScalar ( " ##Sustain " , sliderSize , ImGuiDataType_U8 , & ins - > c64 . s , & _ZERO , & _FIFTEEN ) ) ; rightClickable
2022-04-17 02:51:03 -05:00
ImGui : : TableNextColumn ( ) ;
2023-04-20 04:01:00 -05:00
P ( CWVSliderScalar ( " ##Release " , sliderSize , ImGuiDataType_U8 , & ins - > c64 . r , & _ZERO , & _FIFTEEN ) ) ; rightClickable
2022-04-17 02:51:03 -05:00
ImGui : : TableNextColumn ( ) ;
2024-04-21 12:38:59 -05:00
drawFMEnv ( ( ins - > type = = DIV_INS_SID2 ) ? ( 15 - ins - > sid2 . volume ) : 0 , 16 - ins - > c64 . a , 16 - ins - > c64 . d , 15 - ins - > c64 . r , 15 - ins - > c64 . r , 15 - ins - > c64 . s , 0 , 0 , 0 , 15 , 16 , 15 , ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , sliderSize . y ) , ins - > type ) ;
2022-04-17 02:51:03 -05:00
ImGui : : EndTable ( ) ;
}
2022-02-17 13:08:17 -05:00
2024-05-26 19:31:17 -05:00
P ( CWSliderScalar ( _ ( " Duty " ) , ImGuiDataType_U16 , & ins - > c64 . duty , & _ZERO , & _FOUR_THOUSAND_NINETY_FIVE ) ) ; rightClickable
2022-02-17 13:08:17 -05:00
2024-08-06 09:00:16 +03:00
bool resetDuty = ins - > c64 . resetDuty ;
2024-09-21 17:37:30 -05:00
if ( ImGui : : Checkbox ( _ ( " Reset duty on new note " ) , & resetDuty ) ) { PARAMETER
2024-08-06 09:00:16 +03:00
ins - > c64 . resetDuty = resetDuty ;
}
2022-02-17 13:08:17 -05:00
bool ringMod = ins - > c64 . ringMod ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Checkbox ( _ ( " Ring Modulation " ) , & ringMod ) ) { PARAMETER
2022-02-17 13:08:17 -05:00
ins - > c64 . ringMod = ringMod ;
}
bool oscSync = ins - > c64 . oscSync ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Checkbox ( _ ( " Oscillator Sync " ) , & oscSync ) ) { PARAMETER
2022-02-17 13:08:17 -05:00
ins - > c64 . oscSync = oscSync ;
}
2024-05-26 19:31:17 -05:00
P ( ImGui : : Checkbox ( _ ( " Enable filter " ) , & ins - > c64 . toFilter ) ) ;
P ( ImGui : : Checkbox ( _ ( " Initialize filter " ) , & ins - > c64 . initFilter ) ) ;
2022-02-17 13:08:17 -05:00
2024-04-22 06:21:13 -05:00
if ( ins - > type = = DIV_INS_SID2 ) {
2024-05-26 19:31:17 -05:00
P ( CWSliderScalar ( _ ( " Cutoff " ) , ImGuiDataType_U16 , & ins - > c64 . cut , & _ZERO , & _FOUR_THOUSAND_NINETY_FIVE ) ) ; rightClickable
P ( CWSliderScalar ( _ ( " Resonance " ) , ImGuiDataType_U8 , & ins - > c64 . res , & _ZERO , & _TWO_HUNDRED_FIFTY_FIVE ) ) ; rightClickable
2024-04-22 06:21:13 -05:00
} else {
2024-05-26 19:31:17 -05:00
P ( CWSliderScalar ( _ ( " Cutoff " ) , ImGuiDataType_U16 , & ins - > c64 . cut , & _ZERO , & _TWO_THOUSAND_FORTY_SEVEN ) ) ; rightClickable
P ( CWSliderScalar ( _ ( " Resonance " ) , ImGuiDataType_U8 , & ins - > c64 . res , & _ZERO , & _FIFTEEN ) ) ; rightClickable
2024-04-22 06:21:13 -05:00
}
2022-02-17 13:08:17 -05:00
2023-08-06 22:47:17 -07:00
ImGui : : AlignTextToFramePadding ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Filter Mode " ) ) ;
2022-02-17 13:08:17 -05:00
ImGui : : SameLine ( ) ;
2022-09-10 23:50:53 -05:00
pushToggleColors ( ins - > c64 . lp ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Button ( _ ( " low " ) ) ) { PARAMETER
2022-02-17 13:08:17 -05:00
ins - > c64 . lp = ! ins - > c64 . lp ;
}
2022-09-10 23:50:53 -05:00
popToggleColors ( ) ;
2022-02-17 13:08:17 -05:00
ImGui : : SameLine ( ) ;
2022-09-10 23:50:53 -05:00
pushToggleColors ( ins - > c64 . bp ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Button ( _ ( " band " ) ) ) { PARAMETER
2022-02-17 13:08:17 -05:00
ins - > c64 . bp = ! ins - > c64 . bp ;
}
2022-09-10 23:50:53 -05:00
popToggleColors ( ) ;
2022-02-17 13:08:17 -05:00
ImGui : : SameLine ( ) ;
2022-09-10 23:50:53 -05:00
pushToggleColors ( ins - > c64 . hp ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Button ( _ ( " high " ) ) ) { PARAMETER
2022-02-17 13:08:17 -05:00
ins - > c64 . hp = ! ins - > c64 . hp ;
}
2022-09-10 23:50:53 -05:00
popToggleColors ( ) ;
2024-04-21 12:38:59 -05:00
if ( ins - > type ! = DIV_INS_SID2 ) {
ImGui : : SameLine ( ) ;
pushToggleColors ( ins - > c64 . ch3off ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Button ( _ ( " ch3off " ) ) ) { PARAMETER
2024-04-21 12:38:59 -05:00
ins - > c64 . ch3off = ! ins - > c64 . ch3off ;
}
popToggleColors ( ) ;
}
if ( ins - > type = = DIV_INS_SID2 ) {
2024-05-26 19:31:17 -05:00
P ( CWSliderScalar ( _ ( " Noise Mode " ) , ImGuiDataType_U8 , & ins - > sid2 . noiseMode , & _ZERO , & _THREE ) ) ;
P ( CWSliderScalar ( _ ( " Wave Mix Mode " ) , ImGuiDataType_U8 , & ins - > sid2 . mixMode , & _ZERO , & _THREE , sid2WaveMixModes [ ins - > sid2 . mixMode & 3 ] ) ) ;
2022-02-17 13:08:17 -05:00
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : Checkbox ( _ ( " Absolute Cutoff Macro " ) , & ins - > c64 . filterIsAbs ) ) {
2025-03-10 12:35:05 -05:00
ins - > temp . vZoom [ DIV_MACRO_ALG ] = - 1 ;
2023-03-17 14:54:00 -05:00
PARAMETER ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : Checkbox ( _ ( " Absolute Duty Macro " ) , & ins - > c64 . dutyIsAbs ) ) {
2025-03-10 12:35:05 -05:00
ins - > temp . vZoom [ DIV_MACRO_DUTY ] = - 1 ;
2023-03-17 14:54:00 -05:00
PARAMETER ;
}
2024-04-21 12:38:59 -05:00
if ( ins - > type ! = DIV_INS_SID2 ) {
2024-05-26 19:31:17 -05:00
P ( ImGui : : Checkbox ( _ ( " Don't test before new note " ) , & ins - > c64 . noTest ) ) ;
2024-04-21 12:38:59 -05:00
}
2022-02-17 13:08:17 -05:00
ImGui : : EndTabItem ( ) ;
}
2023-10-21 18:42:37 -05:00
if ( ins - > type = = DIV_INS_SU ) if ( ImGui : : BeginTabItem ( " Sound Unit " ) ) {
2024-05-26 19:31:17 -05:00
P ( ImGui : : Checkbox ( _ ( " Switch roles of frequency and phase reset timer " ) , & ins - > su . switchRoles ) ) ;
2025-08-10 04:53:08 -05:00
if ( ImGui : : BeginChild ( " HWSeqSU " , ImGui : : GetContentRegionAvail ( ) , ImGuiChildFlags_Border , ImGuiWindowFlags_MenuBar ) ) {
2023-10-21 18:42:37 -05:00
ImGui : : BeginMenuBar ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Hardware Sequence " ) ) ;
2023-10-21 18:42:37 -05:00
ImGui : : EndMenuBar ( ) ;
if ( ins - > su . hwSeqLen > 0 ) if ( ImGui : : BeginTable ( " HWSeqListSU " , 3 ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch ) ;
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthFixed ) ;
int curFrame = 0 ;
ImGui : : TableNextRow ( ImGuiTableRowFlags_Headers ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Tick " ) ) ;
2023-10-21 18:42:37 -05:00
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Command " ) ) ;
2023-10-21 18:42:37 -05:00
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Move/Remove " ) ) ;
2023-10-21 18:42:37 -05:00
for ( int i = 0 ; i < ins - > su . hwSeqLen ; i + + ) {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %d (#%d) " , curFrame , i ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : PushID ( i ) ;
if ( ins - > su . hwSeq [ i ] . cmd > = DivInstrumentSoundUnit : : DIV_SU_HWCMD_MAX ) {
ins - > su . hwSeq [ i ] . cmd = 0 ;
}
int cmd = ins - > su . hwSeq [ i ] . cmd ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
2024-05-26 23:30:33 -05:00
if ( ImGui : : Combo ( " ##HWSeqCmd " , & cmd , LocalizedComboGetter , suHWSeqCmdTypes , DivInstrumentSoundUnit : : DIV_SU_HWCMD_MAX ) ) {
2023-10-21 18:42:37 -05:00
if ( ins - > su . hwSeq [ i ] . cmd ! = cmd ) {
ins - > su . hwSeq [ i ] . cmd = cmd ;
ins - > su . hwSeq [ i ] . val = 0 ;
ins - > su . hwSeq [ i ] . bound = 0 ;
ins - > su . hwSeq [ i ] . speed = 0 ;
}
}
bool somethingChanged = false ;
switch ( ins - > su . hwSeq [ i ] . cmd ) {
case DivInstrumentSoundUnit : : DIV_SU_HWCMD_VOL : {
int swPeriod = ins - > su . hwSeq [ i ] . speed ;
int swBound = ins - > su . hwSeq [ i ] . bound ;
int swVal = ins - > su . hwSeq [ i ] . val & 31 ;
bool swDir = ins - > su . hwSeq [ i ] . val & 32 ;
bool swLoop = ins - > su . hwSeq [ i ] . val & 64 ;
bool swInvert = ins - > su . hwSeq [ i ] . val & 128 ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputInt ( _ ( " Period " ) , & swPeriod , 1 , 16 ) ) {
2023-10-21 18:42:37 -05:00
if ( swPeriod < 0 ) swPeriod = 0 ;
if ( swPeriod > 65535 ) swPeriod = 65535 ;
somethingChanged = true ;
}
2024-05-26 19:31:17 -05:00
if ( CWSliderInt ( _ ( " Amount " ) , & swVal , 0 , 31 ) ) {
2023-10-21 18:42:37 -05:00
somethingChanged = true ;
}
2024-05-26 19:31:17 -05:00
if ( CWSliderInt ( _ ( " Bound " ) , & swBound , 0 , 255 ) ) {
2023-10-21 18:42:37 -05:00
somethingChanged = true ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Up " ) , swDir ) ) { PARAMETER
2023-10-21 18:42:37 -05:00
swDir = true ;
somethingChanged = true ;
}
ImGui : : SameLine ( ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Down " ) , ! swDir ) ) { PARAMETER
2023-10-21 18:42:37 -05:00
swDir = false ;
somethingChanged = true ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : Checkbox ( _ ( " Loop " ) , & swLoop ) ) { PARAMETER
2023-10-21 18:42:37 -05:00
somethingChanged = true ;
}
ImGui : : SameLine ( ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Checkbox ( _ ( " Flip " ) , & swInvert ) ) { PARAMETER
2023-10-21 18:42:37 -05:00
somethingChanged = true ;
}
if ( somethingChanged ) {
ins - > su . hwSeq [ i ] . speed = swPeriod ;
ins - > su . hwSeq [ i ] . bound = swBound ;
ins - > su . hwSeq [ i ] . val = ( swVal & 31 ) | ( swDir ? 32 : 0 ) | ( swLoop ? 64 : 0 ) | ( swInvert ? 128 : 0 ) ;
PARAMETER ;
}
break ;
}
case DivInstrumentSoundUnit : : DIV_SU_HWCMD_PITCH :
case DivInstrumentSoundUnit : : DIV_SU_HWCMD_CUT : {
int swPeriod = ins - > su . hwSeq [ i ] . speed ;
int swBound = ins - > su . hwSeq [ i ] . bound ;
int swVal = ins - > su . hwSeq [ i ] . val & 127 ;
bool swDir = ins - > su . hwSeq [ i ] . val & 128 ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputInt ( _ ( " Period " ) , & swPeriod , 1 , 16 ) ) {
2023-10-21 18:42:37 -05:00
if ( swPeriod < 0 ) swPeriod = 0 ;
if ( swPeriod > 65535 ) swPeriod = 65535 ;
somethingChanged = true ;
}
2024-05-26 19:31:17 -05:00
if ( CWSliderInt ( _ ( " Amount " ) , & swVal , 0 , 31 ) ) {
2023-10-21 18:42:37 -05:00
somethingChanged = true ;
}
2024-05-26 19:31:17 -05:00
if ( CWSliderInt ( _ ( " Bound " ) , & swBound , 0 , 255 ) ) {
2023-10-21 18:42:37 -05:00
somethingChanged = true ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Up " ) , swDir ) ) { PARAMETER
2023-10-21 18:42:37 -05:00
swDir = true ;
somethingChanged = true ;
}
ImGui : : SameLine ( ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Down " ) , ! swDir ) ) { PARAMETER
2023-10-21 18:42:37 -05:00
swDir = false ;
somethingChanged = true ;
}
if ( somethingChanged ) {
ins - > su . hwSeq [ i ] . speed = swPeriod ;
ins - > su . hwSeq [ i ] . bound = swBound ;
ins - > su . hwSeq [ i ] . val = ( swVal & 127 ) | ( swDir ? 128 : 0 ) ;
PARAMETER ;
}
break ;
}
case DivInstrumentSoundUnit : : DIV_SU_HWCMD_WAIT : {
int len = ins - > su . hwSeq [ i ] . val + 1 ;
curFrame + = ins - > su . hwSeq [ i ] . val + 1 ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputInt ( _ ( " Ticks " ) , & len ) ) {
2023-10-21 18:42:37 -05:00
if ( len < 1 ) len = 1 ;
if ( len > 255 ) len = 256 ;
somethingChanged = true ;
}
if ( somethingChanged ) {
ins - > su . hwSeq [ i ] . val = len - 1 ;
PARAMETER ;
}
break ;
}
case DivInstrumentSoundUnit : : DIV_SU_HWCMD_WAIT_REL :
curFrame + + ;
break ;
case DivInstrumentSoundUnit : : DIV_SU_HWCMD_LOOP :
case DivInstrumentSoundUnit : : DIV_SU_HWCMD_LOOP_REL : {
int pos = ins - > su . hwSeq [ i ] . val ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputInt ( _ ( " Position " ) , & pos , 1 , 4 ) ) {
2023-10-21 18:42:37 -05:00
if ( pos < 0 ) pos = 0 ;
if ( pos > ( ins - > su . hwSeqLen - 1 ) ) pos = ( ins - > su . hwSeqLen - 1 ) ;
somethingChanged = true ;
}
if ( somethingChanged ) {
ins - > su . hwSeq [ i ] . val = pos ;
PARAMETER ;
}
break ;
}
default :
break ;
}
ImGui : : PopID ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : PushID ( i + 512 ) ;
if ( ImGui : : Button ( ICON_FA_CHEVRON_UP " ##HWCmdUp " ) ) {
if ( i > 0 ) {
e - > lockEngine ( [ ins , i ] ( ) {
ins - > su . hwSeq [ i - 1 ] . cmd ^ = ins - > su . hwSeq [ i ] . cmd ;
ins - > su . hwSeq [ i ] . cmd ^ = ins - > su . hwSeq [ i - 1 ] . cmd ;
ins - > su . hwSeq [ i - 1 ] . cmd ^ = ins - > su . hwSeq [ i ] . cmd ;
ins - > su . hwSeq [ i - 1 ] . speed ^ = ins - > su . hwSeq [ i ] . speed ;
ins - > su . hwSeq [ i ] . speed ^ = ins - > su . hwSeq [ i - 1 ] . speed ;
ins - > su . hwSeq [ i - 1 ] . speed ^ = ins - > su . hwSeq [ i ] . speed ;
ins - > su . hwSeq [ i - 1 ] . val ^ = ins - > su . hwSeq [ i ] . val ;
ins - > su . hwSeq [ i ] . val ^ = ins - > su . hwSeq [ i - 1 ] . val ;
ins - > su . hwSeq [ i - 1 ] . val ^ = ins - > su . hwSeq [ i ] . val ;
ins - > su . hwSeq [ i - 1 ] . bound ^ = ins - > su . hwSeq [ i ] . bound ;
ins - > su . hwSeq [ i ] . bound ^ = ins - > su . hwSeq [ i - 1 ] . bound ;
ins - > su . hwSeq [ i - 1 ] . bound ^ = ins - > su . hwSeq [ i ] . bound ;
} ) ;
}
MARK_MODIFIED ;
}
ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( ICON_FA_CHEVRON_DOWN " ##HWCmdDown " ) ) {
if ( i < ins - > su . hwSeqLen - 1 ) {
e - > lockEngine ( [ ins , i ] ( ) {
ins - > su . hwSeq [ i + 1 ] . cmd ^ = ins - > su . hwSeq [ i ] . cmd ;
ins - > su . hwSeq [ i ] . cmd ^ = ins - > su . hwSeq [ i + 1 ] . cmd ;
ins - > su . hwSeq [ i + 1 ] . cmd ^ = ins - > su . hwSeq [ i ] . cmd ;
ins - > su . hwSeq [ i + 1 ] . speed ^ = ins - > su . hwSeq [ i ] . speed ;
ins - > su . hwSeq [ i ] . speed ^ = ins - > su . hwSeq [ i + 1 ] . speed ;
ins - > su . hwSeq [ i + 1 ] . speed ^ = ins - > su . hwSeq [ i ] . speed ;
ins - > su . hwSeq [ i + 1 ] . val ^ = ins - > su . hwSeq [ i ] . val ;
ins - > su . hwSeq [ i ] . val ^ = ins - > su . hwSeq [ i + 1 ] . val ;
ins - > su . hwSeq [ i + 1 ] . val ^ = ins - > su . hwSeq [ i ] . val ;
ins - > su . hwSeq [ i + 1 ] . bound ^ = ins - > su . hwSeq [ i ] . bound ;
ins - > su . hwSeq [ i ] . bound ^ = ins - > su . hwSeq [ i + 1 ] . bound ;
ins - > su . hwSeq [ i + 1 ] . bound ^ = ins - > su . hwSeq [ i ] . bound ;
} ) ;
}
MARK_MODIFIED ;
}
ImGui : : SameLine ( ) ;
pushDestColor ( ) ;
if ( ImGui : : Button ( ICON_FA_TIMES " ##HWCmdDel " ) ) {
for ( int j = i ; j < ins - > su . hwSeqLen - 1 ; j + + ) {
ins - > su . hwSeq [ j ] . cmd = ins - > su . hwSeq [ j + 1 ] . cmd ;
ins - > su . hwSeq [ j ] . speed = ins - > su . hwSeq [ j + 1 ] . speed ;
ins - > su . hwSeq [ j ] . val = ins - > su . hwSeq [ j + 1 ] . val ;
ins - > su . hwSeq [ j ] . bound = ins - > su . hwSeq [ j + 1 ] . bound ;
}
ins - > su . hwSeqLen - - ;
}
popDestColor ( ) ;
ImGui : : PopID ( ) ;
}
ImGui : : EndTable ( ) ;
}
if ( ImGui : : Button ( ICON_FA_PLUS " ##HWCmdAdd " ) ) {
if ( ins - > su . hwSeqLen < 255 ) {
ins - > su . hwSeq [ ins - > su . hwSeqLen ] . cmd = 0 ;
ins - > su . hwSeq [ ins - > su . hwSeqLen ] . speed = 0 ;
ins - > su . hwSeq [ ins - > su . hwSeqLen ] . val = 0 ;
ins - > su . hwSeq [ ins - > su . hwSeqLen ] . bound = 0 ;
ins - > su . hwSeqLen + + ;
}
}
}
ImGui : : EndChild ( ) ;
ImGui : : EndTabItem ( ) ;
}
2024-09-21 17:37:30 -05:00
if ( ins - > type = = DIV_INS_SID3 ) {
drawInsSID3 ( ins ) ;
}
2023-10-12 20:05:52 -05:00
if ( ins - > type = = DIV_INS_MSM6258 | |
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
ins - > type = = DIV_INS_MSM6295 | |
ins - > type = = DIV_INS_ADPCMA | |
ins - > type = = DIV_INS_ADPCMB | |
ins - > type = = DIV_INS_SEGAPCM | |
ins - > type = = DIV_INS_QSOUND | |
ins - > type = = DIV_INS_YMZ280B | |
ins - > type = = DIV_INS_RF5C68 | |
ins - > type = = DIV_INS_AMIGA | |
ins - > type = = DIV_INS_MULTIPCM | |
ins - > type = = DIV_INS_SU | |
ins - > type = = DIV_INS_SNES | |
2022-12-08 14:18:22 +09:00
ins - > type = = DIV_INS_ES5506 | |
2022-12-15 20:03:54 +09:00
ins - > type = = DIV_INS_K007232 | |
2023-04-02 14:32:47 +09:00
ins - > type = = DIV_INS_GA20 | |
2023-08-09 20:30:00 +09:00
ins - > type = = DIV_INS_K053260 | |
2023-08-28 17:59:34 -05:00
ins - > type = = DIV_INS_C140 | |
2024-01-10 11:17:36 +07:00
ins - > type = = DIV_INS_C219 | |
2024-03-17 15:44:38 -05:00
ins - > type = = DIV_INS_NDS | |
2024-03-16 14:59:02 +07:00
ins - > type = = DIV_INS_GBA_DMA | |
2024-08-09 09:57:35 +03:00
ins - > type = = DIV_INS_GBA_MINMOD | |
ins - > type = = DIV_INS_SUPERVISION ) {
2023-10-12 19:52:44 -05:00
insTabSample ( ins ) ;
2022-02-17 13:08:17 -05:00
}
2023-07-20 16:50:19 -05:00
if ( ins - > type = = DIV_INS_N163 ) if ( ImGui : : BeginTabItem ( " Namco 163 " ) ) {
2023-07-20 18:23:58 -05:00
bool preLoad = ins - > n163 . waveMode & 0x1 ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : Checkbox ( _ ( " Load waveform " ) , & preLoad ) ) { PARAMETER
2023-07-20 18:23:58 -05:00
ins - > n163 . waveMode = ( ins - > n163 . waveMode & ~ 0x1 ) | ( preLoad ? 0x1 : 0 ) ;
}
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " when enabled, a waveform will be loaded into RAM. \n when disabled, only the offset and length change. " ) ) ;
2023-07-20 18:23:58 -05:00
}
if ( preLoad ) {
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputInt ( _ ( " Waveform##WAVE " ) , & ins - > n163 . wave , 1 , 10 ) ) { PARAMETER
2023-07-20 18:23:58 -05:00
if ( ins - > n163 . wave < 0 ) ins - > n163 . wave = 0 ;
if ( ins - > n163 . wave > = e - > song . waveLen ) ins - > n163 . wave = e - > song . waveLen - 1 ;
}
2022-03-24 03:53:07 +09:00
}
2023-07-21 19:54:35 -05:00
ImGui : : Separator ( ) ;
2024-05-26 19:31:17 -05:00
P ( ImGui : : Checkbox ( _ ( " Per-channel wave position/length " ) , & ins - > n163 . perChanPos ) ) ;
2023-07-21 19:54:35 -05:00
if ( ins - > n163 . perChanPos ) {
if ( ImGui : : BeginTable ( " N1PerChPos " , 3 ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch , 0.5f ) ;
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthStretch , 0.5f ) ;
ImGui : : TableNextRow ( ImGuiTableRowFlags_Headers ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Ch " ) ) ;
2023-07-21 19:54:35 -05:00
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Position " ) ) ;
2023-07-21 19:54:35 -05:00
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Length " ) ) ;
2023-07-21 19:54:35 -05:00
for ( int i = 0 ; i < 8 ; i + + ) {
ImGui : : PushID ( 64 + i ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : Dummy ( ImVec2 ( dpiScale , ImGui : : GetFrameHeightWithSpacing ( ) ) ) ;
ImGui : : SameLine ( ) ;
ImGui : : Text ( " %d " , i + 1 ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( ImGui : : InputInt ( " ##pcOff " , & ins - > n163 . wavePosCh [ i ] , 1 , 16 ) ) { PARAMETER
if ( ins - > n163 . wavePosCh [ i ] < 0 ) ins - > n163 . wavePosCh [ i ] = 0 ;
if ( ins - > n163 . wavePosCh [ i ] > 255 ) ins - > n163 . wavePosCh [ i ] = 255 ;
}
ImGui : : TableNextColumn ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ;
if ( ImGui : : InputInt ( " ##pcLen " , & ins - > n163 . waveLenCh [ i ] , 4 , 16 ) ) { PARAMETER
if ( ins - > n163 . waveLenCh [ i ] < 0 ) ins - > n163 . waveLenCh [ i ] = 0 ;
if ( ins - > n163 . waveLenCh [ i ] > 252 ) ins - > n163 . waveLenCh [ i ] = 252 ;
ins - > n163 . waveLenCh [ i ] & = 0xfc ;
}
ImGui : : PopID ( ) ;
}
ImGui : : EndTable ( ) ;
}
} else {
2023-07-29 13:43:49 -05:00
if ( ImGui : : InputInt ( " Position##WAVEPOS " , & ins - > n163 . wavePos , 1 , 16 ) ) { PARAMETER
2023-07-21 19:54:35 -05:00
if ( ins - > n163 . wavePos < 0 ) ins - > n163 . wavePos = 0 ;
if ( ins - > n163 . wavePos > 255 ) ins - > n163 . wavePos = 255 ;
}
if ( ImGui : : InputInt ( " Length##WAVELEN " , & ins - > n163 . waveLen , 4 , 16 ) ) { PARAMETER
if ( ins - > n163 . waveLen < 0 ) ins - > n163 . waveLen = 0 ;
if ( ins - > n163 . waveLen > 252 ) ins - > n163 . waveLen = 252 ;
ins - > n163 . waveLen & = 0xfc ;
}
2022-03-24 03:53:07 +09:00
}
ImGui : : EndTabItem ( ) ;
}
2022-04-04 13:26:02 -05:00
if ( ins - > type = = DIV_INS_FDS ) if ( ImGui : : BeginTabItem ( " FDS " ) ) {
2022-04-05 18:18:14 -05:00
float modTable [ 32 ] ;
2023-02-18 22:40:15 -05:00
int modTableInt [ 256 ] ;
2024-05-26 19:31:17 -05:00
ImGui : : Checkbox ( _ ( " Compatibility mode " ) , & ins - > fds . initModTableWithFirstWave ) ;
2022-04-05 18:18:14 -05:00
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " only use for compatibility with .dmf modules! \n - initializes modulation table with first wavetable \n - does not alter modulation parameters on instrument change " ) ) ;
2022-04-05 18:18:14 -05:00
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputInt ( _ ( " Modulation depth " ) , & ins - > fds . modDepth , 1 , 4 ) ) {
2022-04-05 14:55:17 -05:00
if ( ins - > fds . modDepth < 0 ) ins - > fds . modDepth = 0 ;
if ( ins - > fds . modDepth > 63 ) ins - > fds . modDepth = 63 ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputInt ( _ ( " Modulation speed " ) , & ins - > fds . modSpeed , 1 , 4 ) ) {
2022-04-05 14:55:17 -05:00
if ( ins - > fds . modSpeed < 0 ) ins - > fds . modSpeed = 0 ;
if ( ins - > fds . modSpeed > 4095 ) ins - > fds . modSpeed = 4095 ;
}
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Modulation table " ) ) ;
2022-04-05 18:18:14 -05:00
for ( int i = 0 ; i < 32 ; i + + ) {
modTable [ i ] = ins - > fds . modTable [ i ] ;
2023-02-18 22:40:15 -05:00
modTableInt [ i ] = ins - > fds . modTable [ i ] ;
2022-04-05 18:18:14 -05:00
}
ImVec2 modTableSize = ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , 96.0f * dpiScale ) ;
2025-09-15 06:20:56 -05:00
PlotCustom ( " ##ModTable " , modTable , 32 , 0 , NULL , - 4 , 3 , modTableSize , sizeof ( float ) , ImVec4 ( 1.0f , 1.0f , 1.0f , 1.0f ) , 0 , NULL , NULL , true ) ;
2022-04-05 18:18:14 -05:00
if ( ImGui : : IsItemClicked ( ImGuiMouseButton_Left ) ) {
macroDragStart = ImGui : : GetItemRectMin ( ) ;
macroDragAreaSize = modTableSize ;
macroDragMin = - 4 ;
macroDragMax = 3 ;
macroDragBitMode = false ;
macroDragInitialValueSet = false ;
macroDragInitialValue = false ;
macroDragLen = 32 ;
macroDragActive = true ;
macroDragCTarget = ( unsigned char * ) ins - > fds . modTable ;
macroDragChar = true ;
2022-04-12 23:03:20 -05:00
macroDragLineMode = false ;
macroDragLineInitial = ImVec2 ( 0 , 0 ) ;
processDrags ( ImGui : : GetMousePos ( ) . x , ImGui : : GetMousePos ( ) . y ) ;
2022-12-01 04:28:12 -05:00
ImGui : : InhibitInertialScroll ( ) ;
2022-04-05 18:18:14 -05:00
}
2023-02-18 22:40:15 -05:00
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ; // wavetable text input size found here
if ( ImGui : : InputText ( " ##MMLModTable " , & mmlStringModTable ) ) {
int discardIt = 0 ;
memset ( modTableInt , 0 , 256 * sizeof ( int ) ) ;
decodeMMLStrW ( mmlStringModTable , modTableInt , discardIt , - 4 , 3 , false ) ;
for ( int i = 0 ; i < 32 ; i + + ) {
if ( i > = discardIt ) {
modTableInt [ i ] = 0 ;
} else {
if ( modTableInt [ i ] < - 4 ) modTableInt [ i ] = - 4 ;
if ( modTableInt [ i ] > 3 ) modTableInt [ i ] = 3 ;
}
ins - > fds . modTable [ i ] = modTableInt [ i ] ;
}
MARK_MODIFIED ;
}
if ( ! ImGui : : IsItemActive ( ) ) {
encodeMMLStr ( mmlStringModTable , modTableInt , 32 , - 1 , - 1 , false ) ;
}
2022-04-04 13:26:02 -05:00
ImGui : : EndTabItem ( ) ;
}
2022-10-10 22:17:31 -05:00
if ( ins - > type = = DIV_INS_VBOY ) if ( ImGui : : BeginTabItem ( " Virtual Boy " ) ) {
float modTable [ 32 ] ;
2023-02-18 22:40:15 -05:00
int modTableInt [ 256 ] ;
2024-05-26 19:31:17 -05:00
P ( ImGui : : Checkbox ( _ ( " Set modulation table (channel 5 only) " ) , & ins - > fds . initModTableWithFirstWave ) ) ;
2022-10-10 22:17:31 -05:00
ImGui : : BeginDisabled ( ! ins - > fds . initModTableWithFirstWave ) ;
for ( int i = 0 ; i < 32 ; i + + ) {
modTable [ i ] = ins - > fds . modTable [ i ] ;
2023-02-18 22:40:15 -05:00
modTableInt [ i ] = modTableHex ? ( ( unsigned char ) ins - > fds . modTable [ i ] ) : ins - > fds . modTable [ i ] ;
2022-10-10 22:17:31 -05:00
}
ImVec2 modTableSize = ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , 256.0f * dpiScale ) ;
2025-09-15 06:20:56 -05:00
PlotCustom ( " ##ModTable " , modTable , 32 , 0 , NULL , - 128 , 127 , modTableSize , sizeof ( float ) , ImVec4 ( 1.0f , 1.0f , 1.0f , 1.0f ) , 0 , NULL , NULL , true ) ;
2022-10-10 22:17:31 -05:00
if ( ImGui : : IsItemClicked ( ImGuiMouseButton_Left ) ) {
macroDragStart = ImGui : : GetItemRectMin ( ) ;
macroDragAreaSize = modTableSize ;
macroDragMin = - 128 ;
macroDragMax = 127 ;
macroDragBitMode = false ;
macroDragInitialValueSet = false ;
macroDragInitialValue = false ;
macroDragLen = 32 ;
macroDragActive = true ;
macroDragCTarget = ( unsigned char * ) ins - > fds . modTable ;
macroDragChar = true ;
macroDragLineMode = false ;
macroDragLineInitial = ImVec2 ( 0 , 0 ) ;
processDrags ( ImGui : : GetMousePos ( ) . x , ImGui : : GetMousePos ( ) . y ) ;
2022-12-01 04:28:12 -05:00
ImGui : : InhibitInertialScroll ( ) ;
2022-10-10 22:17:31 -05:00
}
2023-02-18 22:40:15 -05:00
if ( ImGui : : Button ( modTableHex ? " Hex##MTHex " : " Dec##MTHex " ) ) {
modTableHex = ! modTableHex ;
}
ImGui : : SameLine ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetContentRegionAvail ( ) . x ) ; // wavetable text input size found here
if ( ImGui : : InputText ( " ##MMLModTable " , & mmlStringModTable ) ) {
int discardIt = 0 ;
memset ( modTableInt , 0 , 256 * sizeof ( int ) ) ;
decodeMMLStrW ( mmlStringModTable , modTableInt , discardIt , modTableHex ? 0 : - 128 , modTableHex ? 255 : 127 , modTableHex ) ;
for ( int i = 0 ; i < 32 ; i + + ) {
if ( i > = discardIt ) {
modTableInt [ i ] = 0 ;
} else {
if ( modTableInt [ i ] > = 128 ) modTableInt [ i ] - = 256 ;
}
ins - > fds . modTable [ i ] = modTableInt [ i ] ;
}
MARK_MODIFIED ;
}
if ( ! ImGui : : IsItemActive ( ) ) {
encodeMMLStr ( mmlStringModTable , modTableInt , 32 , - 1 , - 1 , modTableHex ) ;
}
ImGui : : SameLine ( ) ;
2022-10-10 22:17:31 -05:00
ImGui : : EndDisabled ( ) ;
ImGui : : EndTabItem ( ) ;
}
2022-04-21 01:52:37 +09:00
if ( ins - > type = = DIV_INS_ES5506 ) if ( ImGui : : BeginTabItem ( " ES5506 " ) ) {
if ( ImGui : : BeginTable ( " ESParams " , 2 , ImGuiTableFlags_SizingStretchSame ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthStretch , 0.0 ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch , 0.0 ) ;
// filter
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
P ( CWSliderScalar ( _ ( " Filter Mode " ) , ImGuiDataType_U8 , & ins - > es5506 . filter . mode , & _ZERO , & _THREE , es5506FilterModes [ ins - > es5506 . filter . mode & 3 ] ) ) ;
2022-04-21 01:52:37 +09:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
P ( CWSliderScalar ( _ ( " Filter K1 " ) , ImGuiDataType_U16 , & ins - > es5506 . filter . k1 , & _ZERO , & _SIXTY_FIVE_THOUSAND_FIVE_HUNDRED_THIRTY_FIVE ) ) ; rightClickable
2022-04-21 01:52:37 +09:00
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
P ( CWSliderScalar ( _ ( " Filter K2 " ) , ImGuiDataType_U16 , & ins - > es5506 . filter . k2 , & _ZERO , & _SIXTY_FIVE_THOUSAND_FIVE_HUNDRED_THIRTY_FIVE ) ) ; rightClickable
2022-04-21 01:52:37 +09:00
// envelope
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
P ( CWSliderScalar ( _ ( " Envelope length " ) , ImGuiDataType_U16 , & ins - > es5506 . envelope . ecount , & _ZERO , & _FIVE_HUNDRED_ELEVEN ) ) ; rightClickable
2022-04-21 01:52:37 +09:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
P ( CWSliderScalar ( _ ( " Left Volume Ramp " ) , ImGuiDataType_S8 , & ins - > es5506 . envelope . lVRamp , & _MINUS_ONE_HUNDRED_TWENTY_EIGHT , & _ONE_HUNDRED_TWENTY_SEVEN ) ) ; rightClickable
2022-04-21 01:52:37 +09:00
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
P ( CWSliderScalar ( _ ( " Right Volume Ramp " ) , ImGuiDataType_S8 , & ins - > es5506 . envelope . rVRamp , & _MINUS_ONE_HUNDRED_TWENTY_EIGHT , & _ONE_HUNDRED_TWENTY_SEVEN ) ) ; rightClickable
2022-04-21 01:52:37 +09:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
P ( CWSliderScalar ( _ ( " Filter K1 Ramp " ) , ImGuiDataType_S8 , & ins - > es5506 . envelope . k1Ramp , & _MINUS_ONE_HUNDRED_TWENTY_EIGHT , & _ONE_HUNDRED_TWENTY_SEVEN ) ) ; rightClickable
2022-04-21 01:52:37 +09:00
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
P ( CWSliderScalar ( _ ( " Filter K2 Ramp " ) , ImGuiDataType_S8 , & ins - > es5506 . envelope . k2Ramp , & _MINUS_ONE_HUNDRED_TWENTY_EIGHT , & _ONE_HUNDRED_TWENTY_SEVEN ) ) ; rightClickable
2022-04-21 01:52:37 +09:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Checkbox ( _ ( " K1 Ramp Slowdown " ) , & ins - > es5506 . envelope . k1Slow ) ;
2022-04-21 01:52:37 +09:00
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
ImGui : : Checkbox ( _ ( " K2 Ramp Slowdown " ) , & ins - > es5506 . envelope . k2Slow ) ;
2022-04-21 01:52:37 +09:00
ImGui : : EndTable ( ) ;
}
ImGui : : EndTabItem ( ) ;
}
2022-05-05 21:20:36 +02:00
if ( ins - > type = = DIV_INS_MULTIPCM ) {
if ( ImGui : : BeginTabItem ( " MultiPCM " ) ) {
ImVec2 sliderSize = ImVec2 ( 20.0f * dpiScale , 128.0 * dpiScale ) ;
if ( ImGui : : BeginTable ( " MultiPCMADSRParams " , 7 , ImGuiTableFlags_NoHostExtendX ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c3 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c4 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c5 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c6 " , ImGuiTableColumnFlags_WidthStretch ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( " AR " ) ;
ImGui : : TextUnformatted ( " AR " ) ;
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Attack Rate " ) ) ;
2022-05-05 21:20:36 +02:00
}
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( " D1R " ) ;
ImGui : : TextUnformatted ( " D1R " ) ;
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Decay 1 Rate " ) ) ;
2022-05-05 21:20:36 +02:00
}
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( " DL " ) ;
ImGui : : TextUnformatted ( " DL " ) ;
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Decay Level " ) ) ;
2022-05-05 21:20:36 +02:00
}
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( " D2R " ) ;
ImGui : : TextUnformatted ( " D2R " ) ;
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Decay 2 Rate " ) ) ;
2022-05-05 21:20:36 +02:00
}
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( " RR " ) ;
ImGui : : TextUnformatted ( " RR " ) ;
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Release Rate " ) ) ;
2022-05-05 21:20:36 +02:00
}
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( " RC " ) ;
ImGui : : TextUnformatted ( " RC " ) ;
if ( ImGui : : IsItemHovered ( ) ) {
2024-05-26 19:31:17 -05:00
ImGui : : SetTooltip ( _ ( " Rate Correction " ) ) ;
2022-05-05 21:20:36 +02:00
}
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
CENTER_TEXT ( _ ( " Envelope " ) ) ;
ImGui : : TextUnformatted ( _ ( " Envelope " ) ) ;
2022-05-05 21:20:36 +02:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2025-09-14 14:21:31 -05:00
P ( CWVSliderScalar ( " ##Attack Rate " , sliderSize , ImGuiDataType_U8 , & ins - > multipcm . ar , & _ZERO , & _FIFTEEN ) ) ; rightClickable
2022-05-05 21:20:36 +02:00
ImGui : : TableNextColumn ( ) ;
2025-09-14 14:21:31 -05:00
P ( CWVSliderScalar ( " ##Decay 1 Rate " , sliderSize , ImGuiDataType_U8 , & ins - > multipcm . d1r , & _ZERO , & _FIFTEEN ) ) ; rightClickable
2022-05-05 21:20:36 +02:00
ImGui : : TableNextColumn ( ) ;
2025-09-14 14:21:31 -05:00
P ( CWVSliderScalar ( " ##Decay Level " , sliderSize , ImGuiDataType_U8 , & ins - > multipcm . dl , & _ZERO , & _FIFTEEN ) ) ; rightClickable
2022-05-05 21:20:36 +02:00
ImGui : : TableNextColumn ( ) ;
2025-09-14 14:21:31 -05:00
P ( CWVSliderScalar ( " ##Decay 2 Rate " , sliderSize , ImGuiDataType_U8 , & ins - > multipcm . d2r , & _ZERO , & _FIFTEEN ) ) ; rightClickable
2022-05-05 21:20:36 +02:00
ImGui : : TableNextColumn ( ) ;
2025-09-14 14:21:31 -05:00
P ( CWVSliderScalar ( " ##Release Rate " , sliderSize , ImGuiDataType_U8 , & ins - > multipcm . rr , & _ZERO , & _FIFTEEN ) ) ; rightClickable
2022-05-05 21:20:36 +02:00
ImGui : : TableNextColumn ( ) ;
2025-09-14 14:21:31 -05:00
P ( CWVSliderScalar ( " ##Rate Correction " , sliderSize , ImGuiDataType_U8 , & ins - > multipcm . rc , & _ZERO , & _FIFTEEN ) ) ; rightClickable
2022-05-05 21:20:36 +02:00
ImGui : : TableNextColumn ( ) ;
2022-09-28 19:33:16 -05:00
drawFMEnv ( 0 , ins - > multipcm . ar , ins - > multipcm . d1r , ins - > multipcm . d2r , ins - > multipcm . rr , ins - > multipcm . dl , 0 , 0 , 0 , 127 , 15 , 15 , ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , sliderSize . y ) , ins - > type ) ;
2022-05-05 21:20:36 +02:00
ImGui : : EndTable ( ) ;
}
if ( ImGui : : BeginTable ( " MultiPCMLFOParams " , 3 , ImGuiTableFlags_SizingStretchSame ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthStretch , 0.0 ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthStretch , 0.0 ) ;
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthStretch , 0.0 ) ;
ImGui : : TableNextColumn ( ) ;
2025-09-14 14:21:31 -05:00
P ( CWSliderScalar ( _ ( " LFO Rate " ) , ImGuiDataType_U8 , & ins - > multipcm . lfo , & _ZERO , & _SEVEN ) ) ; rightClickable
2022-05-05 21:20:36 +02:00
ImGui : : TableNextColumn ( ) ;
2025-09-14 14:21:31 -05:00
P ( CWSliderScalar ( _ ( " PM Depth " ) , ImGuiDataType_U8 , & ins - > multipcm . vib , & _ZERO , & _SEVEN ) ) ; rightClickable
2022-05-05 21:20:36 +02:00
ImGui : : TableNextColumn ( ) ;
2025-09-14 14:21:31 -05:00
P ( CWSliderScalar ( _ ( " AM Depth " ) , ImGuiDataType_U8 , & ins - > multipcm . am , & _ZERO , & _SEVEN ) ) ; rightClickable
2022-05-05 21:20:36 +02:00
ImGui : : EndTable ( ) ;
}
2024-07-13 16:28:20 +09:00
P ( ImGui : : Checkbox ( _ ( " Damp " ) , & ins - > multipcm . damp ) ) ;
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " Only for OPL4 PCM. " ) ) ;
}
P ( ImGui : : Checkbox ( _ ( " Pseudo Reverb " ) , & ins - > multipcm . pseudoReverb ) ) ;
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " Only for OPL4 PCM. " ) ) ;
2024-07-13 13:09:10 +09:00
}
2024-07-13 16:28:20 +09:00
P ( ImGui : : Checkbox ( _ ( " LFO Reset " ) , & ins - > multipcm . lfoReset ) ) ;
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : SetTooltip ( _ ( " Only for OPL4 PCM. " ) ) ;
}
2024-10-09 04:40:24 -05:00
P ( ImGui : : Checkbox ( _ ( " Disable volume change ramp " ) , & ins - > multipcm . levelDirect ) ) ;
2022-05-05 21:20:36 +02:00
ImGui : : EndTabItem ( ) ;
}
}
2022-08-19 19:42:01 -05:00
if ( ins - > type = = DIV_INS_SNES ) if ( ImGui : : BeginTabItem ( " SNES " ) ) {
2024-05-26 19:31:17 -05:00
P ( ImGui : : Checkbox ( _ ( " Use envelope " ) , & ins - > snes . useEnv ) ) ;
2022-08-19 19:42:01 -05:00
ImVec2 sliderSize = ImVec2 ( 20.0f * dpiScale , 128.0 * dpiScale ) ;
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
if ( ins - > snes . useEnv ) {
2022-12-24 18:03:57 -05:00
if ( ImGui : : BeginTable ( " SNESEnvParams " , ins - > snes . sus ? 6 : 5 , ImGuiTableFlags_NoHostExtendX ) ) {
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c2 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
2022-12-24 18:03:57 -05:00
if ( ins - > snes . sus ) {
ImGui : : TableSetupColumn ( " c2x " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
}
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
ImGui : : TableSetupColumn ( " c3 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableSetupColumn ( " c4 " , ImGuiTableColumnFlags_WidthStretch ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( " A " ) ;
ImGui : : TextUnformatted ( " A " ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( " D " ) ;
ImGui : : TextUnformatted ( " D " ) ;
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( " S " ) ;
ImGui : : TextUnformatted ( " S " ) ;
2022-12-24 18:03:57 -05:00
if ( ins - > snes . sus ) {
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( " D2 " ) ;
ImGui : : TextUnformatted ( " D2 " ) ;
}
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
ImGui : : TableNextColumn ( ) ;
CENTER_TEXT ( " R " ) ;
ImGui : : TextUnformatted ( " R " ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
CENTER_TEXT ( _ ( " Envelope " ) ) ;
ImGui : : TextUnformatted ( _ ( " Envelope " ) ) ;
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2023-04-20 04:01:00 -05:00
P ( CWVSliderScalar ( " ##Attack " , sliderSize , ImGuiDataType_U8 , & ins - > snes . a , & _ZERO , & _FIFTEEN ) ) ; rightClickable
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
ImGui : : TableNextColumn ( ) ;
2023-04-20 04:01:00 -05:00
P ( CWVSliderScalar ( " ##Decay " , sliderSize , ImGuiDataType_U8 , & ins - > snes . d , & _ZERO , & _SEVEN ) ) ; rightClickable
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
ImGui : : TableNextColumn ( ) ;
2023-04-20 04:01:00 -05:00
P ( CWVSliderScalar ( " ##Sustain " , sliderSize , ImGuiDataType_U8 , & ins - > snes . s , & _ZERO , & _SEVEN ) ) ; rightClickable
2022-12-24 18:03:57 -05:00
if ( ins - > snes . sus ) {
ImGui : : TableNextColumn ( ) ;
2023-04-20 04:01:00 -05:00
P ( CWVSliderScalar ( " ##Decay2 " , sliderSize , ImGuiDataType_U8 , & ins - > snes . d2 , & _ZERO , & _THIRTY_ONE ) ) ; rightClickable
2022-12-24 18:03:57 -05:00
}
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
ImGui : : TableNextColumn ( ) ;
2023-04-20 04:01:00 -05:00
P ( CWVSliderScalar ( " ##Release " , sliderSize , ImGuiDataType_U8 , & ins - > snes . r , & _ZERO , & _THIRTY_ONE ) ) ; rightClickable
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
ImGui : : TableNextColumn ( ) ;
2022-12-24 18:03:57 -05:00
drawFMEnv ( 0 , ins - > snes . a + 1 , 1 + ins - > snes . d * 2 , ins - > snes . sus ? ins - > snes . d2 : ins - > snes . r , ins - > snes . sus ? ins - > snes . r : 31 , ( 14 - ins - > snes . s * 2 ) , ( ins - > snes . r = = 0 | | ( ins - > snes . sus & & ins - > snes . d2 = = 0 ) ) , 0 , 0 , 7 , 16 , 31 , ImVec2 ( ImGui : : GetContentRegionAvail ( ) . x , sliderSize . y ) , ins - > type ) ;
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
ImGui : : EndTable ( ) ;
}
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " Sustain/release mode: " ) ) ;
if ( ImGui : : RadioButton ( _ ( " Direct (cut on release) " ) , ins - > snes . sus = = 0 ) ) {
2022-12-24 18:03:57 -05:00
ins - > snes . sus = 0 ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Effective (linear decrease) " ) , ins - > snes . sus = = 1 ) ) {
2022-12-24 18:03:57 -05:00
ins - > snes . sus = 1 ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Effective (exponential decrease) " ) , ins - > snes . sus = = 2 ) ) {
2022-12-24 18:03:57 -05:00
ins - > snes . sus = 2 ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Delayed (write R on release) " ) , ins - > snes . sus = = 3 ) ) {
2022-12-24 18:03:57 -05:00
ins - > snes . sus = 3 ;
}
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
} else {
2023-08-24 14:52:18 -05:00
if ( ImGui : : BeginTable ( " SNESGainParams " , 2 , ImGuiTableFlags_NoHostExtendX ) ) {
ImGui : : TableSetupColumn ( " c0 " , ImGuiTableColumnFlags_WidthStretch ) ;
2022-09-24 02:53:11 -05:00
ImGui : : TableSetupColumn ( " c1 " , ImGuiTableColumnFlags_WidthFixed , sliderSize . x ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
CENTER_TEXT ( _ ( " Gain Mode " ) ) ;
ImGui : : TextUnformatted ( _ ( " Gain Mode " ) ) ;
2022-09-24 02:53:11 -05:00
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
CENTER_TEXT ( _ ( " Gain " ) ) ;
ImGui : : TextUnformatted ( _ ( " Gain " ) ) ;
2022-09-24 02:53:11 -05:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Direct " ) , ins - > snes . gainMode = = DivInstrumentSNES : : GAIN_MODE_DIRECT ) ) {
2022-09-24 02:53:11 -05:00
ins - > snes . gainMode = DivInstrumentSNES : : GAIN_MODE_DIRECT ;
PARAMETER ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Decrease (linear) " ) , ins - > snes . gainMode = = DivInstrumentSNES : : GAIN_MODE_DEC_LINEAR ) ) {
2022-09-24 02:53:11 -05:00
ins - > snes . gainMode = DivInstrumentSNES : : GAIN_MODE_DEC_LINEAR ;
PARAMETER ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Decrease (logarithmic) " ) , ins - > snes . gainMode = = DivInstrumentSNES : : GAIN_MODE_DEC_LOG ) ) {
2022-09-24 02:53:11 -05:00
ins - > snes . gainMode = DivInstrumentSNES : : GAIN_MODE_DEC_LOG ;
PARAMETER ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Increase (linear) " ) , ins - > snes . gainMode = = DivInstrumentSNES : : GAIN_MODE_INC_LINEAR ) ) {
2022-09-24 02:53:11 -05:00
ins - > snes . gainMode = DivInstrumentSNES : : GAIN_MODE_INC_LINEAR ;
PARAMETER ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : RadioButton ( _ ( " Increase (bent line) " ) , ins - > snes . gainMode = = DivInstrumentSNES : : GAIN_MODE_INC_INVLOG ) ) {
2022-09-24 02:53:11 -05:00
ins - > snes . gainMode = DivInstrumentSNES : : GAIN_MODE_INC_INVLOG ;
PARAMETER ;
}
ImGui : : TableNextColumn ( ) ;
unsigned char gainMax = ( ins - > snes . gainMode = = DivInstrumentSNES : : GAIN_MODE_DIRECT ) ? 127 : 31 ;
if ( ins - > snes . gain > gainMax ) ins - > snes . gain = gainMax ;
2023-04-20 04:01:00 -05:00
P ( CWVSliderScalar ( " ##Gain " , sliderSize , ImGuiDataType_U8 , & ins - > snes . gain , & _ZERO , & gainMax ) ) ; rightClickable
2022-09-24 02:53:11 -05:00
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
ImGui : : EndTable ( ) ;
}
2023-08-24 14:52:18 -05:00
if ( ins - > snes . gainMode = = DivInstrumentSNES : : GAIN_MODE_DEC_LINEAR | | ins - > snes . gainMode = = DivInstrumentSNES : : GAIN_MODE_DEC_LOG ) {
2024-05-26 19:31:17 -05:00
ImGui : : TextWrapped ( _ ( " using decrease modes will not produce any sound at all, unless you know what you are doing. \n it is recommended to use the Gain macro for decrease instead. " ) ) ;
2023-08-24 14:52:18 -05:00
}
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
}
ImGui : : EndTabItem ( ) ;
}
2022-04-07 18:27:17 -05:00
if ( ins - > type = = DIV_INS_GB | |
2022-04-12 01:19:00 -05:00
( ins - > type = = DIV_INS_AMIGA & & ins - > amiga . useWave ) | |
2024-01-10 11:17:36 +07:00
( ins - > type = = DIV_INS_GBA_DMA & & ins - > amiga . useWave ) | |
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
( ins - > type = = DIV_INS_X1_010 & & ! ins - > amiga . useSample ) | |
2022-04-07 18:27:17 -05:00
ins - > type = = DIV_INS_N163 | |
ins - > type = = DIV_INS_FDS | |
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
( ins - > type = = DIV_INS_SWAN & & ! ins - > amiga . useSample ) | |
( ins - > type = = DIV_INS_PCE & & ! ins - > amiga . useSample ) | |
2022-10-08 23:25:15 -05:00
( ins - > type = = DIV_INS_VBOY ) | |
2022-05-21 02:16:38 -05:00
ins - > type = = DIV_INS_SCC | |
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 16:27:36 +09:00
ins - > type = = DIV_INS_SNES | |
2023-02-11 21:56:41 +09:00
ins - > type = = DIV_INS_NAMCO | |
2024-03-16 14:59:02 +07:00
ins - > type = = DIV_INS_SM8521 | |
2024-08-05 12:28:22 +03:00
( ins - > type = = DIV_INS_GBA_MINMOD & & ins - > amiga . useWave ) )
{
insTabWavetable ( ins ) ;
2022-04-07 18:27:17 -05:00
}
2024-05-26 19:31:17 -05:00
if ( ins - > type < DIV_INS_MAX ) if ( ImGui : : BeginTabItem ( _ ( " Macros " ) ) ) {
2024-05-03 18:34:30 -05:00
// NEW CODE
// this is only the first part of an insEdit refactor.
// don't complain yet!
2024-05-04 13:34:29 -05:00
int waveCount = MAX ( 1 , e - > song . waveLen - 1 ) ;
2024-05-03 18:34:30 -05:00
switch ( ins - > type ) {
case DIV_INS_STD :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise Mode " ) , & ins - > std . dutyMacro , 0 , 3 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , 0 , 2 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , panBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_FM :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 127 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , 0 , 2 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , panBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_GB :
if ( ins - > gb . softEnv ) {
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
2024-05-03 18:34:30 -05:00
}
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Duty/Noise " ) , & ins - > std . dutyMacro , 0 , 3 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , waveCount , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , 0 , 2 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , panBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_C64 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Duty " ) , & ins - > std . dutyMacro , ins - > c64 . dutyIsAbs ? 0 : - 4095 , 4095 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , 4 , 64 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , true , c64ShapeBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Cutoff " ) , & ins - > std . algMacro , ins - > c64 . filterIsAbs ? 0 : - 2047 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_FILTER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Resonance " ) , & ins - > std . ex2Macro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_FILTER ] ) ) ;
2024-07-05 17:03:01 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Filter Mode " ) , & ins - > std . ex1Macro , 0 , 4 , 64 , uiColors [ GUI_COLOR_MACRO_FILTER ] , false , NULL , NULL , true , filtModeBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Filter Toggle " ) , & ins - > std . ex3Macro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_FILTER ] , false , NULL , NULL , true ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Special " ) , & ins - > std . ex4Macro , 0 , 4 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , c64TestGateBits ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Attack " ) , & ins - > std . ex5Macro , 0 , 15 , 128 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Decay " ) , & ins - > std . ex6Macro , 0 , 15 , 128 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Sustain " ) , & ins - > std . ex7Macro , 0 , 15 , 128 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Release " ) , & ins - > std . ex8Macro , 0 , 15 , 128 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_AMIGA :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 64 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , waveCount , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
2024-05-04 13:34:29 -05:00
if ( ins - > std . panLMacro . mode ) {
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , - 16 , 16 , 63 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , macroQSoundMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Surround " ) , & ins - > std . panRMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-04 13:34:29 -05:00
} else {
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 127 , 158 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , macroQSoundMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 127 , 158 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2024-05-04 13:34:29 -05:00
}
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_PCE :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 31 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-05-03 18:34:30 -05:00
if ( ! ins - > amiga . useSample ) {
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise " ) , & ins - > std . dutyMacro , 0 , 1 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-05-03 18:34:30 -05:00
}
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , waveCount , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_AY :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-05-03 18:34:30 -05:00
if ( ! ins - > amiga . useSample ) {
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise Freq " ) , & ins - > std . dutyMacro , 0 , 31 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-08-16 17:55:40 +03:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , 3 , 48 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , true , ayShapeBits ) ) ;
2024-05-03 18:34:30 -05:00
}
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Envelope " ) , & ins - > std . ex2Macro , 0 , 4 , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] , false , NULL , NULL , true , ayEnvBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " AutoEnv Num " ) , & ins - > std . ex3Macro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " AutoEnv Den " ) , & ins - > std . algMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
2024-07-05 16:18:08 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Force Period " ) , & ins - > std . ex4Macro , 0 , 4095 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Env Period " ) , & ins - > std . ex5Macro , 0 , 65535 , 160 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_AY8930 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 31 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-05-03 18:34:30 -05:00
if ( ! ins - > amiga . useSample ) {
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise Freq " ) , & ins - > std . dutyMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , 3 , 64 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , true , ayShapeBits ) ) ;
2024-05-03 18:34:30 -05:00
}
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Duty " ) , & ins - > std . ex1Macro , 0 , 8 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Envelope " ) , & ins - > std . ex2Macro , 0 , 4 , 64 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] , false , NULL , NULL , true , ayEnvBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " AutoEnv Num " ) , & ins - > std . ex3Macro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " AutoEnv Den " ) , & ins - > std . algMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
2024-07-05 16:18:08 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Force Period " ) , & ins - > std . ex4Macro , 0 , 65535 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Env Period " ) , & ins - > std . ex5Macro , 0 , 65535 , 160 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise AND Mask " ) , & ins - > std . fbMacro , 0 , 8 , 96 , uiColors [ GUI_COLOR_MACRO_NOISE ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise OR Mask " ) , & ins - > std . fmsMacro , 0 , 8 , 96 , uiColors [ GUI_COLOR_MACRO_NOISE ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_TIA :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_SAA1099 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Duty/Noise " ) , & ins - > std . dutyMacro , 0 , 3 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , 2 , 64 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , true , ayShapeBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Envelope " ) , & ins - > std . ex1Macro , 0 , 8 , 160 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] , false , NULL , NULL , true , saaEnvBits ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_VIC :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " On/Off " ) , & ins - > std . dutyMacro , 0 , 1 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_PET :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 1 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , 8 , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , true , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_VRC6 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-05-03 18:34:30 -05:00
if ( ! ins - > amiga . useSample ) {
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Duty " ) , & ins - > std . dutyMacro , 0 , 7 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2024-05-04 13:34:29 -05:00
} else {
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , waveCount , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
2024-05-04 13:34:29 -05:00
}
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-05-04 13:34:29 -05:00
if ( ins - > amiga . useSample ) {
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
}
break ;
case DIV_INS_OPLL :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Patch " ) , & ins - > std . waveMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_OPL :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 63 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , 0 , 4 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , panBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_FDS :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 32 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , waveCount , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Mod Depth " ) , & ins - > std . ex1Macro , 0 , 63 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Mod Speed " ) , & ins - > std . ex2Macro , 0 , 4095 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Mod Position " ) , & ins - > std . ex3Macro , 0 , 127 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_VBOY :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise Length " ) , & ins - > std . dutyMacro , 0 , 7 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , waveCount , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_N163 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Wave Pos " ) , & ins - > std . dutyMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , waveCount , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Wave Length " ) , & ins - > std . ex1Macro , 0 , 252 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_SCC :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , waveCount , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_OPZ :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 127 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise Freq " ) , & ins - > std . dutyMacro , 0 , 32 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , 0 , 2 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , panBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_POKEY :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " AUDCTL " ) , & ins - > std . dutyMacro , 0 , 8 , 160 , uiColors [ GUI_COLOR_MACRO_GLOBAL ] , false , NULL , NULL , true , pokeyCtlBits ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , 7 , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-05-03 18:34:30 -05:00
break ;
2024-10-05 19:10:35 -05:00
case DIV_INS_BEEPER : {
bool zxPresent = false ;
for ( int i = 0 ; i < e - > song . systemLen ; i + + ) {
if ( e - > song . system [ i ] = = DIV_SYSTEM_SFX_BEEPER ) {
zxPresent = true ;
break ;
}
}
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 1 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-10-05 19:10:35 -05:00
if ( zxPresent ) {
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pulse Width " ) , & ins - > std . dutyMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
}
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-05-03 18:34:30 -05:00
break ;
2024-10-05 19:10:35 -05:00
}
2024-05-03 18:34:30 -05:00
case DIV_INS_SWAN :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-05-03 18:34:30 -05:00
if ( ! ins - > amiga . useSample ) {
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise " ) , & ins - > std . dutyMacro , 0 , 8 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-05-03 18:34:30 -05:00
}
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , waveCount , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
2024-08-23 20:10:23 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_MIKEY :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 127 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-05-03 18:34:30 -05:00
if ( ! ins - > amiga . useSample ) {
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Duty/Int " ) , & ins - > std . dutyMacro , 0 , 10 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] , false , NULL , NULL , true , mikeyFeedbackBits ) ) ;
2024-05-03 18:34:30 -05:00
}
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Load LFSR " ) , & ins - > std . ex1Macro , 0 , 12 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_VERA :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 63 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Duty " ) , & ins - > std . dutyMacro , 0 , 63 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2025-06-28 00:54:45 +04:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , 3 , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , macroVERAWaves , false , NULL ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , 0 , 2 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , panBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_X1_010 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , waveCount , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-05-04 13:34:29 -05:00
if ( ins - > amiga . useSample ) {
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-04 13:34:29 -05:00
} else {
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Envelope Mode " ) , & ins - > std . ex1Macro , 0 , 7 , 160 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] , false , NULL , NULL , true , x1_010EnvBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Envelope " ) , & ins - > std . ex2Macro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] , false , NULL , NULL , false , ayEnvBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " AutoEnv Num " ) , & ins - > std . ex3Macro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " AutoEnv Den " ) , & ins - > std . algMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
2024-05-04 13:34:29 -05:00
}
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_VRC6_SAW :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 63 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-05-03 18:34:30 -05:00
break ;
2024-06-24 02:44:17 -05:00
case DIV_INS_ES5506 : {
float usesAmigaVol = true ;
for ( int i = 0 ; i < e - > song . systemLen ; i + + ) {
if ( e - > song . system [ i ] = = DIV_SYSTEM_ES5506 ) {
if ( ! e - > song . systemFlags [ i ] . getBool ( " amigaVol " , false ) ) {
usesAmigaVol = false ;
break ;
}
}
}
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , usesAmigaVol ? 64 : 4095 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Filter Mode " ) , & ins - > std . dutyMacro , 0 , 3 , 160 , uiColors [ GUI_COLOR_MACRO_FILTER ] , false , NULL , & macroHoverES5506FilterMode ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 4095 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 4095 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Filter K1 " ) , & ins - > std . ex1Macro , ( ( ins - > std . ex1Macro . mode = = 1 ) ? ( - 65535 ) : 0 ) , 65535 , 160 , uiColors [ GUI_COLOR_MACRO_FILTER ] , false , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Filter K2 " ) , & ins - > std . ex2Macro , ( ( ins - > std . ex2Macro . mode = = 1 ) ? ( - 65535 ) : 0 ) , 65535 , 160 , uiColors [ GUI_COLOR_MACRO_FILTER ] , false , macroRelativeMode ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Outputs " ) , & ins - > std . fbMacro , 0 , 5 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Control " ) , & ins - > std . algMacro , 0 , 2 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , es5506ControlModes ) ) ;
2024-05-03 18:34:30 -05:00
break ;
2024-06-24 02:44:17 -05:00
}
2024-05-03 18:34:30 -05:00
case DIV_INS_MULTIPCM :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 127 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , - 7 , 7 , 45 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-07-13 18:31:28 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " LFO Speed " ) , & ins - > std . ex1Macro , 0 , 7 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " LFO Vib Depth " ) , & ins - > std . fmsMacro , 0 , 7 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " LFO AM Depth " ) , & ins - > std . amsMacro , 0 , 7 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_SNES :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 127 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise Freq " ) , & ins - > std . dutyMacro , 0 , 31 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , waveCount , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 127 , 158 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 127 , 158 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Special " ) , & ins - > std . ex1Macro , 0 , 5 , 96 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , snesModeBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Gain " ) , & ins - > std . ex2Macro , 0 , 255 , 256 , uiColors [ GUI_COLOR_MACRO_VOLUME ] , false , NULL , macroHoverGain , false ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_SU :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 127 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Duty/Noise " ) , & ins - > std . dutyMacro , 0 , 127 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2025-06-28 00:54:45 +04:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , 7 , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , macroSoundUnitWaves , false , NULL ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , - 127 , 127 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Cutoff " ) , & ins - > std . ex1Macro , 0 , 16383 , 160 , uiColors [ GUI_COLOR_MACRO_FILTER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Resonance " ) , & ins - > std . ex2Macro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_FILTER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Control " ) , & ins - > std . ex3Macro , 0 , 4 , 64 , uiColors [ GUI_COLOR_MACRO_FILTER ] , false , NULL , NULL , true , suControlBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset Timer " ) , & ins - > std . ex4Macro , 0 , 65535 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] ) ) ; // again reuse code from resonance macro but use ex4 instead
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_NAMCO :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise " ) , & ins - > std . dutyMacro , 0 , 1 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , waveCount , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_OPL_DRUMS :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 63 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , 0 , 4 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , panBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_OPM :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 127 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise Freq " ) , & ins - > std . dutyMacro , 0 , 32 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , 0 , 2 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , panBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_NES :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Duty/Noise " ) , & ins - > std . dutyMacro , 0 , 3 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_MSM6258 :
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Freq Divider " ) , & ins - > std . dutyMacro , 0 , 2 , 160 , uiColors [ GUI_COLOR_MACRO_GLOBAL ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , 0 , 2 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , panBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Clock Divider " ) , & ins - > std . ex1Macro , 0 , 1 , 160 , uiColors [ GUI_COLOR_MACRO_GLOBAL ] ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_MSM6295 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 8 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Freq Divider " ) , & ins - > std . dutyMacro , 0 , 1 , 160 , uiColors [ GUI_COLOR_MACRO_GLOBAL ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_ADPCMA :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 31 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Global Volume " ) , & ins - > std . dutyMacro , 0 , 63 , 160 , uiColors [ GUI_COLOR_MACRO_GLOBAL ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , 0 , 2 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , panBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_ADPCMB :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , 0 , 2 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , panBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_SEGAPCM :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 127 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 127 , 158 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 127 , 158 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_QSOUND :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 16383 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Echo Level " ) , & ins - > std . dutyMacro , 0 , 32767 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , - 16 , 16 , 63 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Surround " ) , & ins - > std . panRMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Echo Feedback " ) , & ins - > std . ex1Macro , 0 , 16383 , 160 , uiColors [ GUI_COLOR_MACRO_GLOBAL ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Echo Length " ) , & ins - > std . ex2Macro , 0 , 2725 , 160 , uiColors [ GUI_COLOR_MACRO_GLOBAL ] ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_YMZ280B :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , - 7 , 7 , 45 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_RF5C68 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_MSM5232 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 127 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Group Ctrl " ) , & ins - > std . dutyMacro , 0 , 5 , 160 , uiColors [ GUI_COLOR_MACRO_GLOBAL ] , false , NULL , NULL , true , msm5232ControlBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Group Attack " ) , & ins - > std . ex1Macro , 0 , 5 , 96 , uiColors [ GUI_COLOR_MACRO_GLOBAL ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Group Decay " ) , & ins - > std . ex2Macro , 0 , 11 , 160 , uiColors [ GUI_COLOR_MACRO_GLOBAL ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise " ) , & ins - > std . ex3Macro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_NOISE ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_T6W28 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise Type " ) , & ins - > std . dutyMacro , 0 , 1 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_K007232 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_GA20 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_POKEMINI :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 2 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pulse Width " ) , & ins - > std . dutyMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-05-03 18:34:30 -05:00
break ;
2024-08-08 22:58:01 +03:00
case DIV_INS_SUPERVISION :
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Duty/Noise " ) , & ins - > std . dutyMacro , 0 , 3 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-09-05 19:24:42 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise/PCM Pan " ) , & ins - > std . panLMacro , 0 , 2 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , panBits ) ) ;
2024-08-08 22:58:01 +03:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
break ;
2024-05-03 18:34:30 -05:00
case DIV_INS_SM8521 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 31 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , waveCount , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_PV1000 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 1 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_K053260 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 127 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , - 3 , 3 , 37 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_TED :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 8 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Square/Noise " ) , & ins - > std . dutyMacro , 0 , 2 , 80 , uiColors [ GUI_COLOR_MACRO_NOISE ] , false , NULL , NULL , true , tedControlBits ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_C140 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_C219 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Control " ) , & ins - > std . dutyMacro , 0 , 3 , 120 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , c219ControlBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_ESFM :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 63 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " OP4 Noise Mode " ) , & ins - > std . dutyMacro , 0 , 3 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , 0 , 2 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , panBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_POWERNOISE :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Control " ) , & ins - > std . ex1Macro , 0 , 2 , 32 , uiColors [ GUI_COLOR_MACRO_NOISE ] , false , NULL , NULL , true , powerNoiseControlBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Tap A Location " ) , & ins - > std . ex4Macro , 0 , 15 , 96 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Tap B Location " ) , & ins - > std . ex5Macro , 0 , 15 , 96 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Load LFSR " ) , & ins - > std . ex8Macro , 0 , 16 , 256 , uiColors [ GUI_COLOR_MACRO_NOISE ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_POWERNOISE_SLOPE :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 15 , 46 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Control " ) , & ins - > std . ex1Macro , 0 , 6 , 96 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , powerNoiseSlopeControlBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Portion A Length " ) , & ins - > std . ex2Macro , 0 , 255 , 128 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Portion B Length " ) , & ins - > std . ex3Macro , 0 , 255 , 128 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Portion A Offset " ) , & ins - > std . ex6Macro , 0 , 15 , 96 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Portion B Offset " ) , & ins - > std . ex7Macro , 0 , 15 , 96 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_DAVE :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 63 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise Freq " ) , & ins - > std . dutyMacro , 0 , 3 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , 4 , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 63 , 94 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 63 , 94 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Control " ) , & ins - > std . ex1Macro , 0 , 4 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , daveControlBits ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_NDS :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 127 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
2024-05-03 18:34:30 -05:00
if ( ! ins - > amiga . useSample ) {
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Duty " ) , & ins - > std . dutyMacro , 0 , 7 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2024-05-03 18:34:30 -05:00
}
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , - 64 , 63 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_GBA_DMA :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 2 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , waveCount , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning " ) , & ins - > std . panLMacro , 0 , 2 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , panBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_GBA_MINMOD :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , waveCount , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Special " ) , & ins - > std . ex1Macro , 0 , 2 , 96 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , minModModeBits ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_BIFURCATOR :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Parameter " ) , & ins - > std . dutyMacro , 0 , 65535 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Load Value " ) , & ins - > std . ex1Macro , 0 , 65535 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2024-05-03 18:34:30 -05:00
break ;
case DIV_INS_SID2 :
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 15 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Duty " ) , & ins - > std . dutyMacro , ins - > c64 . dutyIsAbs ? 0 : - 4095 , 4095 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , 4 , 64 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , true , c64ShapeBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Cutoff " ) , & ins - > std . algMacro , ins - > c64 . filterIsAbs ? 0 : - 4095 , 4095 , 160 , uiColors [ GUI_COLOR_MACRO_FILTER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Resonance " ) , & ins - > std . ex2Macro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_FILTER ] ) ) ;
2024-07-05 17:03:01 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Filter Mode " ) , & ins - > std . ex1Macro , 0 , 3 , 64 , uiColors [ GUI_COLOR_MACRO_FILTER ] , false , NULL , NULL , true , filtModeBits ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Filter Toggle " ) , & ins - > std . ex3Macro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_FILTER ] , false , NULL , NULL , true ) ) ;
2024-05-26 19:31:17 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Special " ) , & ins - > std . ex4Macro , 0 , 3 , 48 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , sid2ControlBits ) ) ;
2024-07-04 18:08:07 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Attack " ) , & ins - > std . ex5Macro , 0 , 15 , 128 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Decay " ) , & ins - > std . ex6Macro , 0 , 15 , 128 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Sustain " ) , & ins - > std . ex7Macro , 0 , 15 , 128 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Release " ) , & ins - > std . ex8Macro , 0 , 15 , 128 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise Mode " ) , & ins - > std . fmsMacro , 0 , 3 , 64 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
2024-08-10 14:21:28 +03:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Wave Mix " ) , & ins - > std . amsMacro , 0 , 3 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , macroSID2WaveMixMode ) ) ;
2024-05-03 18:34:30 -05:00
break ;
2024-08-11 09:22:49 +03:00
case DIV_INS_UPD1771C :
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 31 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , 7 , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Wave Pos " ) , & ins - > std . ex1Macro , 0 , 31 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Duty/Mode " ) , & ins - > std . dutyMacro , 0 , 1 , 160 , uiColors [ GUI_COLOR_MACRO_NOISE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
2024-05-03 18:34:30 -05:00
break ;
2024-09-13 23:46:03 -05:00
case DIV_INS_SID3 :
2024-09-21 17:37:30 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Volume " ) , & ins - > std . volMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_VOLUME ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Arpeggio " ) , & ins - > std . arpMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . arpMacro . val ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Pitch " ) , & ins - > std . pitchMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode ) ) ;
if ( ins - > sid3 . doWavetable ) {
int waveCount = MAX ( 1 , e - > song . waveLen - 1 ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , waveCount , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , false , NULL ) ) ;
} else {
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Duty " ) , & ins - > std . dutyMacro , ins - > sid3 . dutyIsAbs ? 0 : - 65535 , 65535 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Waveform " ) , & ins - > std . waveMacro , 0 , 5 , 16 * 5 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , NULL , true , sid3ShapeBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Special Wave " ) , & ins - > std . algMacro , 0 , SID3_NUM_SPECIAL_WAVES - 1 , 160 , uiColors [ GUI_COLOR_MACRO_WAVE ] , false , NULL , macroSID3SpecialWaves ) ) ;
}
if ( ins - > sid3 . separateNoisePitch & & ! ins - > sid3 . doWavetable ) {
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise Arpeggio " ) , & ins - > std . opMacros [ 3 ] . amMacro , - 120 , 120 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , NULL , macroHoverNote , false , NULL , true , ins - > std . opMacros [ 3 ] . amMacro . val , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise Pitch " ) , & ins - > std . opMacros [ 0 ] . arMacro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode , NULL , false , NULL , false , NULL , false , true ) ) ;
}
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (left) " ) , & ins - > std . panLMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Panning (right) " ) , & ins - > std . panRMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Channel inversion " ) , & ins - > std . opMacros [ 2 ] . arMacro , 0 , 2 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , minModModeBits ) ) ;
2024-05-03 18:34:30 -05:00
2024-09-21 17:37:30 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Key On/Off " ) , & ins - > std . opMacros [ 0 ] . amMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Special " ) , & ins - > std . ex1Macro , 0 , 3 , 48 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true , sid3ControlBits ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Ring Mod Source " ) , & ins - > std . fmsMacro , 0 , SID3_NUM_CHANNELS , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , macroSID3SourceChan ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Hard Sync Source " ) , & ins - > std . amsMacro , 0 , SID3_NUM_CHANNELS - 1 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , macroSID3SourceChan ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Mod Source " ) , & ins - > std . fbMacro , 0 , SID3_NUM_CHANNELS - 1 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , macroSID3SourceChan ) ) ;
if ( ! ins - > sid3 . doWavetable ) {
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Feedback " ) , & ins - > std . opMacros [ 3 ] . arMacro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
}
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Phase Reset " ) , & ins - > std . phaseResetMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
if ( ! ins - > sid3 . doWavetable ) {
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise Phase Reset " ) , & ins - > std . opMacros [ 1 ] . amMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
}
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Envelope Reset " ) , & ins - > std . opMacros [ 2 ] . amMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Attack " ) , & ins - > std . ex2Macro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Decay " ) , & ins - > std . ex3Macro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Sustain " ) , & ins - > std . ex4Macro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Sustain Rate " ) , & ins - > std . ex5Macro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Release " ) , & ins - > std . ex6Macro , 0 , 255 , 160 , uiColors [ GUI_COLOR_MACRO_ENVELOPE ] ) ) ;
if ( ! ins - > sid3 . doWavetable ) {
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Noise LFSR bits " ) , & ins - > std . ex7Macro , 0 , 30 , 16 * 30 , uiColors [ GUI_COLOR_MACRO_NOISE ] , false , NULL , macroSID3NoiseLFSR , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " 1-Bit Noise " ) , & ins - > std . opMacros [ 1 ] . arMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_NOISE ] , false , NULL , NULL , true ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Wave Mix " ) , & ins - > std . ex8Macro , 0 , 4 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , macroSID3WaveMixMode ) ) ;
} else {
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Sample Mode " ) , & ins - > std . opMacros [ 1 ] . arMacro , 0 , 1 , 32 , uiColors [ GUI_COLOR_MACRO_NOISE ] , false , NULL , NULL , true ) ) ;
}
2024-09-13 23:46:03 -05:00
break ;
2024-05-03 18:34:30 -05:00
case DIV_INS_MAX :
case DIV_INS_NULL :
break ;
}
2025-03-10 12:46:46 -05:00
drawMacros ( macroList , macroEditStateMacros , ins ) ;
2022-02-17 13:08:17 -05:00
ImGui : : EndTabItem ( ) ;
}
2024-08-02 16:52:54 -05:00
if ( ins - > type = = DIV_INS_AY ) {
if ( ! ins - > amiga . useSample )
{
if ( ImGui : : BeginTabItem ( _ ( " Timer Macros " ) ) )
{
2025-10-04 18:39:07 -05:00
ImGui : : Text ( _ ( " warning: timer effects require direct stream mode to be enabled during VGM export! " ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Timer FX " ) , & ins - > std . ex6Macro , 0 , 2 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] , false , NULL , macroTFXModes ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Timer Offset " ) , & ins - > std . ex7Macro , - 2048 , 2047 , 160 , uiColors [ GUI_COLOR_MACRO_PITCH ] , true , macroRelativeMode , NULL , false , NULL , false , NULL , false , true ) ) ;
2024-08-02 16:52:54 -05:00
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Timer Num " ) , & ins - > std . ex8Macro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " Timer Den " ) , & ins - > std . fmsMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
macroList . push_back ( FurnaceGUIMacroDesc ( _ ( " PWM Boundary " ) , & ins - > std . amsMacro , 0 , 15 , 64 , uiColors [ GUI_COLOR_MACRO_OTHER ] ) ) ;
2025-03-10 12:46:46 -05:00
drawMacros ( macroList , macroEditStateMacros , ins ) ;
2024-08-02 16:52:54 -05:00
ImGui : : EndTabItem ( ) ;
}
}
}
2024-01-25 13:30:20 -05:00
if ( ins - > type = = DIV_INS_POWERNOISE | | ins - > type = = DIV_INS_POWERNOISE_SLOPE ) {
2024-01-25 12:49:46 -05:00
if ( ImGui : : BeginTabItem ( " PowerNoise " ) ) {
int pnOctave = ins - > powernoise . octave ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : InputInt ( _ ( " Octave offset " ) , & pnOctave , 1 , 4 ) ) { PARAMETER
2024-01-25 12:49:46 -05:00
if ( pnOctave < 0 ) pnOctave = 0 ;
if ( pnOctave > 15 ) pnOctave = 15 ;
ins - > powernoise . octave = pnOctave ;
}
2024-05-26 19:31:17 -05:00
ImGui : : Text ( _ ( " go to Macros for other parameters. " ) ) ;
2024-01-25 12:49:46 -05:00
ImGui : : EndTabItem ( ) ;
}
}
2023-10-12 20:05:52 -05:00
if ( ins - > type = = DIV_INS_NES | |
ins - > type = = DIV_INS_AY | |
ins - > type = = DIV_INS_AY8930 | |
ins - > type = = DIV_INS_MIKEY | |
ins - > type = = DIV_INS_PCE | |
ins - > type = = DIV_INS_X1_010 | |
ins - > type = = DIV_INS_SWAN | |
ins - > type = = DIV_INS_VRC6 ) {
2023-10-12 19:52:44 -05:00
insTabSample ( ins ) ;
}
2023-12-18 10:56:45 -05:00
if ( ins - > type > = DIV_INS_MAX ) {
2024-05-26 19:31:17 -05:00
if ( ImGui : : BeginTabItem ( _ ( " Error " ) ) ) {
ImGui : : Text ( _ ( " invalid instrument type! change it first. " ) ) ;
2023-12-18 10:56:45 -05:00
ImGui : : EndTabItem ( ) ;
}
}
2022-02-17 13:08:17 -05:00
ImGui : : EndTabBar ( ) ;
}
2022-04-12 21:30:12 -05:00
if ( settings . insEditColorize ) {
popAccentColors ( ) ;
}
2022-02-17 13:08:17 -05:00
}
2022-05-08 18:32:16 -05:00
if ( displayMacroMenu ) {
displayMacroMenu = false ;
if ( lastMacroDesc . macro ! = NULL ) {
ImGui : : OpenPopup ( " macroMenu " ) ;
}
}
2022-05-08 17:35:21 -05:00
if ( ImGui : : BeginPopup ( " macroMenu " , ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings ) ) {
2024-05-26 19:31:17 -05:00
if ( ImGui : : MenuItem ( _ ( " copy " ) ) ) {
2022-05-08 18:32:16 -05:00
String mmlStr ;
encodeMMLStr ( mmlStr , lastMacroDesc . macro - > val , lastMacroDesc . macro - > len , lastMacroDesc . macro - > loop , lastMacroDesc . macro - > rel ) ;
SDL_SetClipboardText ( mmlStr . c_str ( ) ) ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : MenuItem ( _ ( " paste " ) ) ) {
2022-05-08 18:32:16 -05:00
String mmlStr ;
char * clipText = SDL_GetClipboardText ( ) ;
if ( clipText ! = NULL ) {
if ( clipText [ 0 ] ) {
mmlStr = clipText ;
}
SDL_free ( clipText ) ;
}
if ( ! mmlStr . empty ( ) ) {
decodeMMLStr ( mmlStr , lastMacroDesc . macro - > val , lastMacroDesc . macro - > len , lastMacroDesc . macro - > loop , lastMacroDesc . min , ( lastMacroDesc . isBitfield ) ? ( ( 1 < < ( lastMacroDesc . isBitfield ? lastMacroDesc . max : 0 ) ) - 1 ) : lastMacroDesc . max , lastMacroDesc . macro - > rel ) ;
}
}
ImGui : : Separator ( ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : MenuItem ( _ ( " clear " ) ) ) {
2022-05-08 18:32:16 -05:00
lastMacroDesc . macro - > len = 0 ;
2022-08-22 02:13:33 -05:00
lastMacroDesc . macro - > loop = 255 ;
lastMacroDesc . macro - > rel = 255 ;
2022-05-08 18:32:16 -05:00
for ( int i = 0 ; i < 256 ; i + + ) {
lastMacroDesc . macro - > val [ i ] = 0 ;
}
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : MenuItem ( _ ( " clear contents " ) ) ) {
2022-05-08 18:32:16 -05:00
for ( int i = 0 ; i < 256 ; i + + ) {
lastMacroDesc . macro - > val [ i ] = 0 ;
}
}
ImGui : : Separator ( ) ;
2024-05-26 19:31:17 -05:00
if ( ImGui : : BeginMenu ( _ ( " offset... " ) ) ) {
ImGui : : InputInt ( _ ( " X " ) , & macroOffX , 1 , 10 ) ;
ImGui : : InputInt ( _ ( " Y " ) , & macroOffY , 1 , 10 ) ;
if ( ImGui : : Button ( _ ( " offset " ) ) ) {
2022-05-08 18:32:16 -05:00
int oldData [ 256 ] ;
memset ( oldData , 0 , 256 * sizeof ( int ) ) ;
memcpy ( oldData , lastMacroDesc . macro - > val , lastMacroDesc . macro - > len * sizeof ( int ) ) ;
for ( int i = 0 ; i < lastMacroDesc . macro - > len ; i + + ) {
int val = 0 ;
2025-04-08 16:41:12 -05:00
bool bit30 = false ;
2022-05-08 18:32:16 -05:00
if ( ( i - macroOffX ) > = 0 & & ( i - macroOffX ) < lastMacroDesc . macro - > len ) {
2025-04-08 16:41:12 -05:00
bit30 = enBit30 ( oldData [ i - macroOffX ] ) ;
val = deBit30 ( oldData [ i - macroOffX ] ) + macroOffY ;
2022-05-08 18:32:16 -05:00
if ( val < lastMacroDesc . min ) val = lastMacroDesc . min ;
if ( val > lastMacroDesc . max ) val = lastMacroDesc . max ;
}
2025-04-08 16:41:12 -05:00
lastMacroDesc . macro - > val [ i ] = val ^ ( bit30 ? 0x40000000 : 0 ) ;
2022-05-08 18:32:16 -05:00
}
2022-08-22 02:13:33 -05:00
if ( lastMacroDesc . macro - > loop < lastMacroDesc . macro - > len ) {
2022-05-08 18:32:16 -05:00
lastMacroDesc . macro - > loop + = macroOffX ;
} else {
2022-08-22 02:13:33 -05:00
lastMacroDesc . macro - > loop = 255 ;
2022-05-08 18:32:16 -05:00
}
if ( ( lastMacroDesc . macro - > rel + macroOffX ) > = 0 & & ( lastMacroDesc . macro - > rel + macroOffX ) < lastMacroDesc . macro - > len ) {
lastMacroDesc . macro - > rel + = macroOffX ;
} else {
2022-08-22 02:13:33 -05:00
lastMacroDesc . macro - > rel = 255 ;
2022-05-08 18:32:16 -05:00
}
ImGui : : CloseCurrentPopup ( ) ;
}
ImGui : : EndMenu ( ) ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : BeginMenu ( _ ( " scale... " ) ) ) {
if ( ImGui : : InputFloat ( _ ( " X " ) , & macroScaleX , 1.0f , 10.0f , " %.2f%% " ) ) {
2022-05-08 18:32:16 -05:00
if ( macroScaleX < 0.1 ) macroScaleX = 0.1 ;
if ( macroScaleX > 12800.0 ) macroScaleX = 12800.0 ;
}
2024-05-26 19:31:17 -05:00
ImGui : : InputFloat ( _ ( " Y " ) , & macroScaleY , 1.0f , 10.0f , " %.2f%% " ) ;
if ( ImGui : : Button ( _ ( " scale " ) ) ) {
2022-05-08 18:32:16 -05:00
int oldData [ 256 ] ;
memset ( oldData , 0 , 256 * sizeof ( int ) ) ;
memcpy ( oldData , lastMacroDesc . macro - > val , lastMacroDesc . macro - > len * sizeof ( int ) ) ;
2024-04-14 09:18:23 -05:00
lastMacroDesc . macro - > len = MIN ( 255 , ( ( double ) lastMacroDesc . macro - > len * ( macroScaleX / 100.0 ) ) ) ;
2022-05-08 18:32:16 -05:00
for ( int i = 0 ; i < lastMacroDesc . macro - > len ; i + + ) {
int val = 0 ;
2025-04-08 16:41:12 -05:00
bool bit30 = false ;
2022-05-08 18:32:16 -05:00
double posX = round ( ( double ) i * ( 100.0 / macroScaleX ) - 0.01 ) ;
if ( posX > = 0 & & posX < lastMacroDesc . macro - > len ) {
2025-04-08 16:41:12 -05:00
val = round ( ( double ) deBit30 ( oldData [ ( int ) posX ] ) * ( macroScaleY / 100.0 ) ) ;
bit30 = enBit30 ( oldData [ ( int ) posX ] ) ;
2022-05-08 18:32:16 -05:00
if ( val < lastMacroDesc . min ) val = lastMacroDesc . min ;
if ( val > lastMacroDesc . max ) val = lastMacroDesc . max ;
}
2025-04-08 16:41:12 -05:00
lastMacroDesc . macro - > val [ i ] = val ^ ( bit30 ? 0x40000000 : 0 ) ;
2022-05-08 18:32:16 -05:00
}
ImGui : : CloseCurrentPopup ( ) ;
}
ImGui : : EndMenu ( ) ;
}
2024-05-26 19:31:17 -05:00
if ( ImGui : : BeginMenu ( _ ( " randomize... " ) ) ) {
2022-09-16 00:18:14 -05:00
if ( macroRandMin < lastMacroDesc . min ) macroRandMin = lastMacroDesc . min ;
if ( macroRandMin > lastMacroDesc . max ) macroRandMin = lastMacroDesc . max ;
if ( macroRandMax < lastMacroDesc . min ) macroRandMax = lastMacroDesc . min ;
if ( macroRandMax > lastMacroDesc . max ) macroRandMax = lastMacroDesc . max ;
2024-05-26 19:31:17 -05:00
ImGui : : InputInt ( _ ( " Min " ) , & macroRandMin , 1 , 10 ) ;
ImGui : : InputInt ( _ ( " Max " ) , & macroRandMax , 1 , 10 ) ;
if ( ImGui : : Button ( _ ( " randomize " ) ) ) {
2022-09-16 00:18:14 -05:00
for ( int i = 0 ; i < lastMacroDesc . macro - > len ; i + + ) {
int val = 0 ;
if ( macroRandMax < = macroRandMin ) {
val = macroRandMin ;
} else {
val = macroRandMin + ( rand ( ) % ( macroRandMax - macroRandMin + 1 ) ) ;
}
lastMacroDesc . macro - > val [ i ] = val ;
}
ImGui : : CloseCurrentPopup ( ) ;
}
ImGui : : EndMenu ( ) ;
}
2022-05-08 18:32:16 -05:00
2022-05-08 17:35:21 -05:00
ImGui : : EndPopup ( ) ;
}
2022-02-17 13:08:17 -05:00
}
2024-08-23 13:17:19 -07:00
2024-08-19 02:49:14 -05:00
if ( ImGui : : IsWindowFocused ( ImGuiFocusedFlags_ChildWindows ) ) curWindow = GUI_WINDOW_INS_EDIT ;
ImGui : : End ( ) ;
2022-03-22 14:48:48 +07:00
}
2024-08-23 13:17:19 -07:00
void FurnaceGUI : : checkRecordInstrumentUndoStep ( ) {
if ( insEditOpen & & curIns > = 0 & & curIns < ( int ) e - > song . ins . size ( ) ) {
DivInstrument * ins = e - > song . ins [ curIns ] ;
// invalidate cachedCurIns/any possible changes if the cachedCurIns was referencing a different
// instrument altgoether
bool insChanged = ins ! = cachedCurInsPtr ;
if ( insChanged ) {
insEditMayBeDirty = false ;
cachedCurInsPtr = ins ;
cachedCurIns = * ins ;
}
cachedCurInsPtr = ins ;
// check against the last cached to see if diff -- note that modifications to instruments
// happen outside drawInsEdit (e.g. cursor inputs are processed and can directly modify
// macro data). but don't check until we think the user input is complete.
bool delayDiff = ImGui : : IsMouseDown ( ImGuiMouseButton_Left ) | | ImGui : : IsMouseDown ( ImGuiMouseButton_Right ) | | ImGui : : GetIO ( ) . WantCaptureKeyboard ;
if ( ! delayDiff & & insEditMayBeDirty ) {
bool hasChange = ins - > recordUndoStepIfChanged ( e - > processTime , & cachedCurIns ) ;
if ( hasChange ) {
cachedCurIns = * ins ;
}
insEditMayBeDirty = false ;
}
} else {
cachedCurInsPtr = NULL ;
insEditMayBeDirty = false ;
}
}
void FurnaceGUI : : doUndoInstrument ( ) {
if ( ! insEditOpen ) return ;
if ( curIns < 0 | | curIns > = ( int ) e - > song . ins . size ( ) ) return ;
DivInstrument * ins = e - > song . ins [ curIns ] ;
// is locking the engine necessary? copied from doUndoSample
e - > lockEngine ( [ this , ins ] ( ) {
ins - > undo ( ) ;
cachedCurInsPtr = ins ;
cachedCurIns = * ins ;
} ) ;
}
void FurnaceGUI : : doRedoInstrument ( ) {
if ( ! insEditOpen ) return ;
if ( curIns < 0 | | curIns > = ( int ) e - > song . ins . size ( ) ) return ;
DivInstrument * ins = e - > song . ins [ curIns ] ;
// is locking the engine necessary? copied from doRedoSample
e - > lockEngine ( [ this , ins ] ( ) {
ins - > redo ( ) ;
cachedCurInsPtr = ins ;
cachedCurIns = * ins ;
} ) ;
}