| 
									
										
										
										
											2022-02-14 22:12:20 -05:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Furnace Tracker - multi-system chiptune tracker | 
					
						
							|  |  |  |  * Copyright (C) 2021-2022 tildearrow and contributors | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-15 17:42:48 -04:00
										 |  |  | #ifndef _INSTRUMENT_H
 | 
					
						
							|  |  |  | #define _INSTRUMENT_H
 | 
					
						
							| 
									
										
										
										
											2022-01-19 03:28:29 -05:00
										 |  |  | #include "safeWriter.h"
 | 
					
						
							| 
									
										
										
										
											2022-01-22 00:14:48 -05:00
										 |  |  | #include "dataErrors.h"
 | 
					
						
							| 
									
										
										
										
											2021-05-12 18:19:18 -04:00
										 |  |  | #include "../ta-utils.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-06 22:36:32 -05:00
										 |  |  | // NOTICE!
 | 
					
						
							|  |  |  | // before adding new instrument types to this struct, please ask me first.
 | 
					
						
							|  |  |  | // absolutely zero support granted to conflicting formats.
 | 
					
						
							| 
									
										
										
										
											2022-04-10 17:52:03 -04:00
										 |  |  | enum DivInstrumentType: unsigned short { | 
					
						
							| 
									
										
										
										
											2022-01-09 03:52:41 -05:00
										 |  |  |   DIV_INS_STD=0, | 
					
						
							|  |  |  |   DIV_INS_FM=1, | 
					
						
							|  |  |  |   DIV_INS_GB=2, | 
					
						
							|  |  |  |   DIV_INS_C64=3, | 
					
						
							| 
									
										
										
										
											2022-01-13 13:55:33 -05:00
										 |  |  |   DIV_INS_AMIGA=4, | 
					
						
							|  |  |  |   DIV_INS_PCE=5, | 
					
						
							| 
									
										
										
										
											2022-01-14 00:02:10 -05:00
										 |  |  |   DIV_INS_AY=6, | 
					
						
							| 
									
										
										
										
											2022-01-14 15:21:57 -05:00
										 |  |  |   DIV_INS_AY8930=7, | 
					
						
							| 
									
										
										
										
											2022-01-14 23:26:22 -05:00
										 |  |  |   DIV_INS_TIA=8, | 
					
						
							| 
									
										
										
										
											2022-02-02 18:24:33 -05:00
										 |  |  |   DIV_INS_SAA1099=9, | 
					
						
							|  |  |  |   DIV_INS_VIC=10, | 
					
						
							|  |  |  |   DIV_INS_PET=11, | 
					
						
							|  |  |  |   DIV_INS_VRC6=12, | 
					
						
							|  |  |  |   DIV_INS_OPLL=13, | 
					
						
							|  |  |  |   DIV_INS_OPL=14, | 
					
						
							|  |  |  |   DIV_INS_FDS=15, | 
					
						
							|  |  |  |   DIV_INS_VBOY=16, | 
					
						
							|  |  |  |   DIV_INS_N163=17, | 
					
						
							|  |  |  |   DIV_INS_SCC=18, | 
					
						
							|  |  |  |   DIV_INS_OPZ=19, | 
					
						
							|  |  |  |   DIV_INS_POKEY=20, | 
					
						
							|  |  |  |   DIV_INS_BEEPER=21, | 
					
						
							|  |  |  |   DIV_INS_SWAN=22, | 
					
						
							| 
									
										
										
										
											2022-02-20 12:15:15 -05:00
										 |  |  |   DIV_INS_MIKEY=23, | 
					
						
							| 
									
										
										
										
											2022-03-06 22:21:51 -05:00
										 |  |  |   DIV_INS_VERA=24, | 
					
						
							|  |  |  |   DIV_INS_X1_010=25, | 
					
						
							| 
									
										
										
										
											2022-03-31 16:25:58 -04:00
										 |  |  |   DIV_INS_VRC6_SAW=26, | 
					
						
							| 
									
										
										
										
											2022-04-27 01:56:15 -04:00
										 |  |  |   DIV_INS_ES5506=27, | 
					
						
							|  |  |  |   DIV_INS_MULTIPCM=28, | 
					
						
							|  |  |  |   DIV_INS_SNES=29, | 
					
						
							|  |  |  |   DIV_INS_SU=30, | 
					
						
							| 
									
										
										
										
											2022-05-20 03:43:39 -04:00
										 |  |  |   DIV_INS_NAMCO=31, | 
					
						
							| 
									
										
										
										
											2022-05-30 19:37:07 -04:00
										 |  |  |   DIV_INS_OPL_DRUMS=32, | 
					
						
							| 
									
										
										
										
											2022-03-06 22:21:51 -05:00
										 |  |  |   DIV_INS_MAX, | 
					
						
							| 
									
										
										
										
											2022-04-27 01:56:15 -04:00
										 |  |  |   DIV_INS_NULL | 
					
						
							| 
									
										
										
										
											2021-05-11 16:08:08 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-01 02:38:10 -05:00
										 |  |  | // FM operator structure:
 | 
					
						
							|  |  |  | // - OPN:
 | 
					
						
							|  |  |  | //   - AM, AR, DR, MULT, RR, SL, TL, RS, DT, D2R, SSG-EG
 | 
					
						
							|  |  |  | // - OPM:
 | 
					
						
							|  |  |  | //   - AM, AR, DR, MULT, RR, SL, TL, DT2, RS, DT, D2R
 | 
					
						
							|  |  |  | // - OPLL:
 | 
					
						
							|  |  |  | //   - AM, AR, DR, MULT, RR, SL, TL, SSG-EG&8 = EG-S
 | 
					
						
							|  |  |  | //   - KSL, VIB, KSR
 | 
					
						
							|  |  |  | // - OPL:
 | 
					
						
							|  |  |  | //   - AM, AR, DR, MULT, RR, SL, TL, SSG-EG&8 = EG-S
 | 
					
						
							|  |  |  | //   - KSL, VIB, WS (OPL2/3), KSR
 | 
					
						
							| 
									
										
										
										
											2022-04-06 23:56:06 -04:00
										 |  |  | // - OPZ:
 | 
					
						
							| 
									
										
										
										
											2022-03-01 02:38:10 -05:00
										 |  |  | //   - AM, AR, DR, MULT (CRS), RR, SL, TL, DT2, RS, DT, D2R
 | 
					
						
							| 
									
										
										
										
											2022-04-06 23:56:06 -04:00
										 |  |  | //   - WS, DVB = MULT (FINE), DAM = REV, KSL = EGShift, EGT = Fixed
 | 
					
						
							| 
									
										
										
										
											2022-03-01 02:38:10 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-11 16:08:08 -04:00
										 |  |  | struct DivInstrumentFM { | 
					
						
							| 
									
										
										
										
											2022-04-07 01:45:53 -04:00
										 |  |  |   unsigned char alg, fb, fms, ams, fms2, ams2, ops, opllPreset; | 
					
						
							| 
									
										
										
										
											2022-03-04 01:18:16 -05:00
										 |  |  |   bool fixedDrums; | 
					
						
							|  |  |  |   unsigned short kickFreq, snareHatFreq, tomTopFreq; | 
					
						
							| 
									
										
										
										
											2021-05-12 18:19:18 -04:00
										 |  |  |   struct Operator { | 
					
						
							| 
									
										
										
										
											2022-04-10 01:01:55 -04:00
										 |  |  |     bool enable; | 
					
						
							| 
									
										
										
										
											2021-05-11 16:26:38 -04:00
										 |  |  |     unsigned char am, ar, dr, mult, rr, sl, tl, dt2, rs, dt, d2r, ssgEnv; | 
					
						
							| 
									
										
										
										
											2022-03-01 02:38:10 -05:00
										 |  |  |     unsigned char dam, dvb, egt, ksl, sus, vib, ws, ksr; // YMU759/OPL/OPZ
 | 
					
						
							| 
									
										
										
										
											2021-12-12 18:19:43 -05:00
										 |  |  |     Operator(): | 
					
						
							| 
									
										
										
										
											2022-04-10 17:52:03 -04:00
										 |  |  |       enable(true), | 
					
						
							| 
									
										
										
										
											2021-12-12 18:19:43 -05:00
										 |  |  |       am(0), | 
					
						
							|  |  |  |       ar(0), | 
					
						
							|  |  |  |       dr(0), | 
					
						
							|  |  |  |       mult(0), | 
					
						
							|  |  |  |       rr(0), | 
					
						
							|  |  |  |       sl(0), | 
					
						
							|  |  |  |       tl(0), | 
					
						
							|  |  |  |       dt2(0), | 
					
						
							|  |  |  |       rs(0), | 
					
						
							|  |  |  |       dt(0), | 
					
						
							|  |  |  |       d2r(0), | 
					
						
							|  |  |  |       ssgEnv(0), | 
					
						
							|  |  |  |       dam(0), | 
					
						
							|  |  |  |       dvb(0), | 
					
						
							|  |  |  |       egt(0), | 
					
						
							|  |  |  |       ksl(0), | 
					
						
							|  |  |  |       sus(0), | 
					
						
							|  |  |  |       vib(0), | 
					
						
							|  |  |  |       ws(0), | 
					
						
							|  |  |  |       ksr(0) {} | 
					
						
							| 
									
										
										
										
											2021-05-11 16:08:08 -04:00
										 |  |  |   } op[4]; | 
					
						
							| 
									
										
										
										
											2021-12-12 18:19:43 -05:00
										 |  |  |   DivInstrumentFM(): | 
					
						
							|  |  |  |     alg(0), | 
					
						
							|  |  |  |     fb(0), | 
					
						
							|  |  |  |     fms(0), | 
					
						
							|  |  |  |     ams(0), | 
					
						
							| 
									
										
										
										
											2022-04-07 01:45:53 -04:00
										 |  |  |     fms2(0), | 
					
						
							|  |  |  |     ams2(0), | 
					
						
							| 
									
										
										
										
											2022-03-17 03:13:45 -04:00
										 |  |  |     ops(2), | 
					
						
							| 
									
										
										
										
											2022-03-04 01:18:16 -05:00
										 |  |  |     opllPreset(0), | 
					
						
							|  |  |  |     fixedDrums(false), | 
					
						
							|  |  |  |     kickFreq(0x520), | 
					
						
							|  |  |  |     snareHatFreq(0x550), | 
					
						
							|  |  |  |     tomTopFreq(0x1c0) { | 
					
						
							| 
									
										
										
										
											2021-12-27 17:21:43 -05:00
										 |  |  |     // default instrument
 | 
					
						
							|  |  |  |     fb=4; | 
					
						
							|  |  |  |     op[0].tl=42; | 
					
						
							|  |  |  |     op[0].ar=31; | 
					
						
							| 
									
										
										
										
											2022-03-17 15:32:01 -04:00
										 |  |  |     op[0].dr=8; | 
					
						
							| 
									
										
										
										
											2021-12-27 17:21:43 -05:00
										 |  |  |     op[0].sl=15; | 
					
						
							|  |  |  |     op[0].rr=3; | 
					
						
							|  |  |  |     op[0].mult=5; | 
					
						
							|  |  |  |     op[0].dt=5; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     op[2].tl=18; | 
					
						
							|  |  |  |     op[2].ar=31; | 
					
						
							|  |  |  |     op[2].dr=10; | 
					
						
							|  |  |  |     op[2].sl=15; | 
					
						
							|  |  |  |     op[2].rr=4; | 
					
						
							|  |  |  |     op[2].mult=1; | 
					
						
							|  |  |  |     op[2].dt=0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-17 15:32:01 -04:00
										 |  |  |     op[1].tl=48; | 
					
						
							| 
									
										
										
										
											2021-12-27 17:21:43 -05:00
										 |  |  |     op[1].ar=31; | 
					
						
							| 
									
										
										
										
											2022-03-17 15:32:01 -04:00
										 |  |  |     op[1].dr=4; | 
					
						
							| 
									
										
										
										
											2021-12-27 17:21:43 -05:00
										 |  |  |     op[1].sl=11; | 
					
						
							| 
									
										
										
										
											2022-03-17 15:32:01 -04:00
										 |  |  |     op[1].rr=1; | 
					
						
							| 
									
										
										
										
											2021-12-27 17:21:43 -05:00
										 |  |  |     op[1].mult=1; | 
					
						
							|  |  |  |     op[1].dt=5; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     op[3].tl=2; | 
					
						
							|  |  |  |     op[3].ar=31; | 
					
						
							|  |  |  |     op[3].dr=9; | 
					
						
							|  |  |  |     op[3].sl=15; | 
					
						
							|  |  |  |     op[3].rr=9; | 
					
						
							|  |  |  |     op[3].mult=1; | 
					
						
							|  |  |  |     op[3].dt=0; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-05-11 16:08:08 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-04 05:47:52 -04:00
										 |  |  | // this is getting out of hand
 | 
					
						
							| 
									
										
										
										
											2022-04-10 01:01:55 -04:00
										 |  |  | struct DivInstrumentMacro { | 
					
						
							|  |  |  |   String name; | 
					
						
							|  |  |  |   int val[256]; | 
					
						
							|  |  |  |   unsigned int mode; | 
					
						
							|  |  |  |   bool open; | 
					
						
							| 
									
										
										
										
											2022-08-22 03:13:33 -04:00
										 |  |  |   unsigned char len, delay, speed, loop, rel; | 
					
						
							| 
									
										
										
										
											2022-05-07 17:25:02 -04:00
										 |  |  |    | 
					
						
							|  |  |  |   // the following variables are used by the GUI and not saved in the file
 | 
					
						
							|  |  |  |   int vScroll, vZoom; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-14 19:25:59 -04:00
										 |  |  |   explicit DivInstrumentMacro(const String& n, bool initOpen=false): | 
					
						
							| 
									
										
										
										
											2022-04-10 01:01:55 -04:00
										 |  |  |     name(n), | 
					
						
							|  |  |  |     mode(0), | 
					
						
							|  |  |  |     open(initOpen), | 
					
						
							|  |  |  |     len(0), | 
					
						
							| 
									
										
										
										
											2022-08-22 03:13:33 -04:00
										 |  |  |     delay(0), | 
					
						
							|  |  |  |     speed(1), | 
					
						
							|  |  |  |     loop(255), | 
					
						
							|  |  |  |     rel(255), | 
					
						
							| 
									
										
										
										
											2022-05-07 17:25:02 -04:00
										 |  |  |     vScroll(0), | 
					
						
							|  |  |  |     vZoom(-1) { | 
					
						
							| 
									
										
										
										
											2022-04-10 04:26:50 -04:00
										 |  |  |     memset(val,0,256*sizeof(int)); | 
					
						
							| 
									
										
										
										
											2022-04-10 17:52:03 -04:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-04-10 01:01:55 -04:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2022-04-04 05:47:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-10 01:01:55 -04:00
										 |  |  | struct DivInstrumentSTD { | 
					
						
							|  |  |  |   DivInstrumentMacro volMacro; | 
					
						
							|  |  |  |   DivInstrumentMacro arpMacro; | 
					
						
							|  |  |  |   DivInstrumentMacro dutyMacro; | 
					
						
							|  |  |  |   DivInstrumentMacro waveMacro; | 
					
						
							|  |  |  |   DivInstrumentMacro pitchMacro; | 
					
						
							|  |  |  |   DivInstrumentMacro ex1Macro; | 
					
						
							|  |  |  |   DivInstrumentMacro ex2Macro; | 
					
						
							|  |  |  |   DivInstrumentMacro ex3Macro; | 
					
						
							|  |  |  |   DivInstrumentMacro algMacro; | 
					
						
							|  |  |  |   DivInstrumentMacro fbMacro; | 
					
						
							|  |  |  |   DivInstrumentMacro fmsMacro; | 
					
						
							|  |  |  |   DivInstrumentMacro amsMacro; | 
					
						
							|  |  |  |   DivInstrumentMacro panLMacro; | 
					
						
							|  |  |  |   DivInstrumentMacro panRMacro; | 
					
						
							|  |  |  |   DivInstrumentMacro phaseResetMacro; | 
					
						
							|  |  |  |   DivInstrumentMacro ex4Macro; | 
					
						
							|  |  |  |   DivInstrumentMacro ex5Macro; | 
					
						
							|  |  |  |   DivInstrumentMacro ex6Macro; | 
					
						
							|  |  |  |   DivInstrumentMacro ex7Macro; | 
					
						
							|  |  |  |   DivInstrumentMacro ex8Macro; | 
					
						
							| 
									
										
										
										
											2022-04-04 05:47:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 16:32:53 -05:00
										 |  |  |   struct OpMacro { | 
					
						
							|  |  |  |     // ar, dr, mult, rr, sl, tl, dt2, rs, dt, d2r, ssgEnv;
 | 
					
						
							| 
									
										
										
										
											2022-04-10 01:01:55 -04:00
										 |  |  |     DivInstrumentMacro amMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro arMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro drMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro multMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro rrMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro slMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro tlMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro dt2Macro; | 
					
						
							|  |  |  |     DivInstrumentMacro rsMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro dtMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro d2rMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro ssgMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro damMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro dvbMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro egtMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro kslMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro susMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro vibMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro wsMacro; | 
					
						
							|  |  |  |     DivInstrumentMacro ksrMacro; | 
					
						
							| 
									
										
										
										
											2022-01-18 16:32:53 -05:00
										 |  |  |     OpMacro(): | 
					
						
							| 
									
										
										
										
											2022-04-10 01:01:55 -04:00
										 |  |  |       amMacro("am"), arMacro("ar"), drMacro("dr"), multMacro("mult"), | 
					
						
							| 
									
										
										
										
											2022-04-10 17:52:03 -04:00
										 |  |  |       rrMacro("rr"), slMacro("sl"), tlMacro("tl",true), dt2Macro("dt2"), | 
					
						
							| 
									
										
										
										
											2022-04-10 01:01:55 -04:00
										 |  |  |       rsMacro("rs"), dtMacro("dt"), d2rMacro("d2r"), ssgMacro("ssg"), | 
					
						
							|  |  |  |       damMacro("dam"), dvbMacro("dvb"), egtMacro("egt"), kslMacro("ksl"), | 
					
						
							|  |  |  |       susMacro("sus"), vibMacro("vib"), wsMacro("ws"), ksrMacro("ksr") {} | 
					
						
							| 
									
										
										
										
											2022-01-18 16:32:53 -05:00
										 |  |  |   } opMacros[4]; | 
					
						
							| 
									
										
										
										
											2021-12-12 18:19:43 -05:00
										 |  |  |   DivInstrumentSTD(): | 
					
						
							| 
									
										
										
										
											2022-04-10 17:52:03 -04:00
										 |  |  |     volMacro("vol",true), | 
					
						
							| 
									
										
										
										
											2022-04-10 01:01:55 -04:00
										 |  |  |     arpMacro("arp"), | 
					
						
							| 
									
										
										
										
											2022-04-10 17:52:03 -04:00
										 |  |  |     dutyMacro("duty"), | 
					
						
							|  |  |  |     waveMacro("wave"), | 
					
						
							| 
									
										
										
										
											2022-04-10 01:01:55 -04:00
										 |  |  |     pitchMacro("pitch"), | 
					
						
							|  |  |  |     ex1Macro("ex1"), | 
					
						
							|  |  |  |     ex2Macro("ex2"), | 
					
						
							|  |  |  |     ex3Macro("ex3"), | 
					
						
							|  |  |  |     algMacro("alg"), | 
					
						
							|  |  |  |     fbMacro("fb"), | 
					
						
							|  |  |  |     fmsMacro("fms"), | 
					
						
							|  |  |  |     amsMacro("ams"), | 
					
						
							|  |  |  |     panLMacro("panL"), | 
					
						
							|  |  |  |     panRMacro("panR"), | 
					
						
							|  |  |  |     phaseResetMacro("phaseReset"), | 
					
						
							|  |  |  |     ex4Macro("ex4"), | 
					
						
							|  |  |  |     ex5Macro("ex5"), | 
					
						
							|  |  |  |     ex6Macro("ex6"),  | 
					
						
							|  |  |  |     ex7Macro("ex7"), | 
					
						
							|  |  |  |     ex8Macro("ex8") {} | 
					
						
							| 
									
										
										
										
											2021-05-11 16:08:08 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct DivInstrumentGB { | 
					
						
							| 
									
										
										
										
											2022-08-07 01:03:27 -04:00
										 |  |  |   unsigned char envVol, envDir, envLen, soundLen, hwSeqLen; | 
					
						
							| 
									
										
										
										
											2022-08-10 02:55:44 -04:00
										 |  |  |   bool softEnv, alwaysInit; | 
					
						
							| 
									
										
										
										
											2022-08-07 02:32:28 -04:00
										 |  |  |   enum HWSeqCommands: unsigned char { | 
					
						
							|  |  |  |     DIV_GB_HWCMD_ENVELOPE=0, | 
					
						
							|  |  |  |     DIV_GB_HWCMD_SWEEP, | 
					
						
							|  |  |  |     DIV_GB_HWCMD_WAIT, | 
					
						
							|  |  |  |     DIV_GB_HWCMD_WAIT_REL, | 
					
						
							|  |  |  |     DIV_GB_HWCMD_LOOP, | 
					
						
							|  |  |  |     DIV_GB_HWCMD_LOOP_REL, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     DIV_GB_HWCMD_MAX | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2022-08-07 01:03:27 -04:00
										 |  |  |   struct HWSeqCommand { | 
					
						
							|  |  |  |     unsigned char cmd; | 
					
						
							|  |  |  |     unsigned short data; | 
					
						
							|  |  |  |   } hwSeq[256]; | 
					
						
							| 
									
										
										
										
											2021-12-12 18:19:43 -05:00
										 |  |  |   DivInstrumentGB(): | 
					
						
							| 
									
										
										
										
											2021-12-17 22:14:41 -05:00
										 |  |  |     envVol(15), | 
					
						
							| 
									
										
										
										
											2021-12-12 18:19:43 -05:00
										 |  |  |     envDir(0), | 
					
						
							| 
									
										
										
										
											2021-12-17 22:14:41 -05:00
										 |  |  |     envLen(2), | 
					
						
							| 
									
										
										
										
											2022-08-07 01:03:27 -04:00
										 |  |  |     soundLen(64), | 
					
						
							| 
									
										
										
										
											2022-08-10 02:55:44 -04:00
										 |  |  |     hwSeqLen(0), | 
					
						
							|  |  |  |     softEnv(false), | 
					
						
							|  |  |  |     alwaysInit(false) { | 
					
						
							| 
									
										
										
										
											2022-08-07 01:03:27 -04:00
										 |  |  |     memset(hwSeq,0,256*sizeof(int)); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-05-11 16:08:08 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct DivInstrumentC64 { | 
					
						
							|  |  |  |   bool triOn, sawOn, pulseOn, noiseOn; | 
					
						
							|  |  |  |   unsigned char a, d, s, r; | 
					
						
							| 
									
										
										
										
											2022-01-09 17:00:52 -05:00
										 |  |  |   unsigned short duty; | 
					
						
							| 
									
										
										
										
											2021-05-11 16:08:08 -04:00
										 |  |  |   unsigned char ringMod, oscSync; | 
					
						
							| 
									
										
										
										
											2022-04-28 00:54:45 -04:00
										 |  |  |   bool toFilter, volIsCutoff, initFilter, dutyIsAbs, filterIsAbs, noTest; | 
					
						
							| 
									
										
										
										
											2022-01-09 17:00:52 -05:00
										 |  |  |   unsigned char res; | 
					
						
							|  |  |  |   unsigned short cut; | 
					
						
							| 
									
										
										
										
											2021-05-11 16:08:08 -04:00
										 |  |  |   bool hp, lp, bp, ch3off; | 
					
						
							| 
									
										
										
										
											2021-12-12 18:19:43 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   DivInstrumentC64(): | 
					
						
							|  |  |  |     triOn(false), | 
					
						
							|  |  |  |     sawOn(true), | 
					
						
							|  |  |  |     pulseOn(false), | 
					
						
							|  |  |  |     noiseOn(false), | 
					
						
							|  |  |  |     a(0), | 
					
						
							|  |  |  |     d(8), | 
					
						
							|  |  |  |     s(0), | 
					
						
							|  |  |  |     r(0), | 
					
						
							| 
									
										
										
										
											2022-01-09 17:00:52 -05:00
										 |  |  |     duty(2048), | 
					
						
							| 
									
										
										
										
											2021-12-12 18:19:43 -05:00
										 |  |  |     ringMod(0), | 
					
						
							|  |  |  |     oscSync(0), | 
					
						
							|  |  |  |     toFilter(false), | 
					
						
							|  |  |  |     volIsCutoff(false), | 
					
						
							|  |  |  |     initFilter(false), | 
					
						
							| 
									
										
										
										
											2022-01-09 03:52:41 -05:00
										 |  |  |     dutyIsAbs(false), | 
					
						
							|  |  |  |     filterIsAbs(false), | 
					
						
							| 
									
										
										
										
											2022-04-28 00:54:45 -04:00
										 |  |  |     noTest(false), | 
					
						
							| 
									
										
										
										
											2021-12-12 18:19:43 -05:00
										 |  |  |     res(0), | 
					
						
							|  |  |  |     cut(0), | 
					
						
							|  |  |  |     hp(false), | 
					
						
							|  |  |  |     lp(false), | 
					
						
							|  |  |  |     bp(false), | 
					
						
							|  |  |  |     ch3off(false) {} | 
					
						
							| 
									
										
										
										
											2021-05-11 16:08:08 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-09 03:52:41 -05:00
										 |  |  | struct DivInstrumentAmiga { | 
					
						
							| 
									
										
										
										
											2022-07-20 10:01:06 -04:00
										 |  |  |   struct SampleMap { | 
					
						
							|  |  |  |     int freq; | 
					
						
							|  |  |  |     short map; | 
					
						
							|  |  |  |     SampleMap(int f=0, short m=-1): | 
					
						
							|  |  |  |       freq(f), | 
					
						
							|  |  |  |       map(m) {} | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2022-01-09 03:52:41 -05:00
										 |  |  |   short initSample; | 
					
						
							| 
									
										
										
										
											2022-03-16 18:01:44 -04:00
										 |  |  |   bool useNoteMap; | 
					
						
							| 
									
										
										
										
											2022-04-12 02:19:00 -04:00
										 |  |  |   bool useWave; | 
					
						
							|  |  |  |   unsigned char waveLen; | 
					
						
							| 
									
										
										
										
											2022-07-20 10:01:06 -04:00
										 |  |  |   SampleMap noteMap[120]; | 
					
						
							| 
									
										
										
										
											2022-01-09 03:52:41 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-13 19:46:52 -04:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * get the sample at specified note. | 
					
						
							|  |  |  |    * @return the sample. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   inline short getSample(int note) { | 
					
						
							|  |  |  |     if (useNoteMap) { | 
					
						
							|  |  |  |       if (note<0) note=0; | 
					
						
							|  |  |  |       if (note>119) note=119; | 
					
						
							| 
									
										
										
										
											2022-07-20 10:01:06 -04:00
										 |  |  |       return noteMap[note].map; | 
					
						
							| 
									
										
										
										
											2022-05-13 19:46:52 -04:00
										 |  |  |     } | 
					
						
							|  |  |  |     return initSample; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * get the sample frequency at specified note. | 
					
						
							|  |  |  |    * @return the frequency, or -1 if not using note map. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   inline int getFreq(int note) { | 
					
						
							|  |  |  |     if (useNoteMap) { | 
					
						
							|  |  |  |       if (note<0) note=0; | 
					
						
							|  |  |  |       if (note>119) note=119; | 
					
						
							| 
									
										
										
										
											2022-07-20 10:01:06 -04:00
										 |  |  |       return noteMap[note].freq; | 
					
						
							| 
									
										
										
										
											2022-05-13 19:46:52 -04:00
										 |  |  |     } | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-09 03:52:41 -05:00
										 |  |  |   DivInstrumentAmiga(): | 
					
						
							| 
									
										
										
										
											2022-03-16 18:01:44 -04:00
										 |  |  |     initSample(0), | 
					
						
							| 
									
										
										
										
											2022-04-12 02:19:00 -04:00
										 |  |  |     useNoteMap(false), | 
					
						
							|  |  |  |     useWave(false), | 
					
						
							|  |  |  |     waveLen(31) { | 
					
						
							| 
									
										
										
										
											2022-07-20 10:01:06 -04:00
										 |  |  |     for (SampleMap& elem: noteMap) { | 
					
						
							|  |  |  |       elem=SampleMap(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-03-16 18:01:44 -04:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-01-09 03:52:41 -05:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-23 14:53:07 -04:00
										 |  |  | struct DivInstrumentN163 { | 
					
						
							|  |  |  |   int wave, wavePos, waveLen; | 
					
						
							|  |  |  |   unsigned char waveMode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   DivInstrumentN163(): | 
					
						
							|  |  |  |     wave(-1), | 
					
						
							|  |  |  |     wavePos(0), | 
					
						
							| 
									
										
										
										
											2022-03-27 23:04:01 -04:00
										 |  |  |     waveLen(32), | 
					
						
							|  |  |  |     waveMode(3) {} | 
					
						
							| 
									
										
										
										
											2022-03-23 14:53:07 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-03 23:37:16 -04:00
										 |  |  | struct DivInstrumentFDS { | 
					
						
							|  |  |  |   signed char modTable[32]; | 
					
						
							| 
									
										
										
										
											2022-04-04 05:47:52 -04:00
										 |  |  |   int modSpeed, modDepth; | 
					
						
							|  |  |  |   // this is here for compatibility.
 | 
					
						
							|  |  |  |   bool initModTableWithFirstWave; | 
					
						
							| 
									
										
										
										
											2022-04-03 23:37:16 -04:00
										 |  |  |   DivInstrumentFDS(): | 
					
						
							|  |  |  |     modSpeed(0), | 
					
						
							| 
									
										
										
										
											2022-04-04 05:47:52 -04:00
										 |  |  |     modDepth(0), | 
					
						
							|  |  |  |     initModTableWithFirstWave(false) { | 
					
						
							| 
									
										
										
										
											2022-04-03 23:37:16 -04:00
										 |  |  |     memset(modTable,0,32); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-05 15:20:36 -04:00
										 |  |  | struct DivInstrumentMultiPCM { | 
					
						
							|  |  |  |   unsigned char ar, d1r, dl, d2r, rr, rc; | 
					
						
							|  |  |  |   unsigned char lfo, vib, am; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   DivInstrumentMultiPCM(): | 
					
						
							|  |  |  |     ar(15), d1r(15), dl(0), d2r(0), rr(15), rc(15), | 
					
						
							|  |  |  |     lfo(0), vib(0), am(0) { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-07 16:46:48 -04:00
										 |  |  | enum DivWaveSynthEffects { | 
					
						
							|  |  |  |   DIV_WS_NONE=0, | 
					
						
							|  |  |  |   // one waveform effects
 | 
					
						
							|  |  |  |   DIV_WS_INVERT, | 
					
						
							|  |  |  |   DIV_WS_ADD, | 
					
						
							|  |  |  |   DIV_WS_SUBTRACT, | 
					
						
							|  |  |  |   DIV_WS_AVERAGE, | 
					
						
							|  |  |  |   DIV_WS_PHASE, | 
					
						
							| 
									
										
										
										
											2022-05-21 19:36:15 -04:00
										 |  |  |   DIV_WS_CHORUS, | 
					
						
							| 
									
										
										
										
											2022-04-07 19:27:17 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   DIV_WS_SINGLE_MAX, | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2022-04-07 16:46:48 -04:00
										 |  |  |   // two waveform effects
 | 
					
						
							|  |  |  |   DIV_WS_NONE_DUAL=128, | 
					
						
							|  |  |  |   DIV_WS_WIPE, | 
					
						
							|  |  |  |   DIV_WS_FADE, | 
					
						
							|  |  |  |   DIV_WS_PING_PONG, | 
					
						
							|  |  |  |   DIV_WS_OVERLAY, | 
					
						
							|  |  |  |   DIV_WS_NEGATIVE_OVERLAY, | 
					
						
							| 
									
										
										
										
											2022-05-21 19:36:15 -04:00
										 |  |  |   DIV_WS_SLIDE, | 
					
						
							|  |  |  |   DIV_WS_MIX, | 
					
						
							|  |  |  |   DIV_WS_PHASE_MOD, | 
					
						
							| 
									
										
										
										
											2022-04-07 19:27:17 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   DIV_WS_DUAL_MAX | 
					
						
							| 
									
										
										
										
											2022-04-07 16:46:48 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct DivInstrumentWaveSynth { | 
					
						
							|  |  |  |   int wave1, wave2; | 
					
						
							| 
									
										
										
										
											2022-04-08 05:34:39 -04:00
										 |  |  |   unsigned char rateDivider; | 
					
						
							| 
									
										
										
										
											2022-04-07 19:27:17 -04:00
										 |  |  |   unsigned char effect; | 
					
						
							| 
									
										
										
										
											2022-04-07 16:46:48 -04:00
										 |  |  |   bool oneShot, enabled, global; | 
					
						
							|  |  |  |   unsigned char speed, param1, param2, param3, param4; | 
					
						
							|  |  |  |   DivInstrumentWaveSynth(): | 
					
						
							|  |  |  |     wave1(0), | 
					
						
							|  |  |  |     wave2(0), | 
					
						
							|  |  |  |     rateDivider(1), | 
					
						
							|  |  |  |     effect(DIV_WS_NONE), | 
					
						
							|  |  |  |     oneShot(false), | 
					
						
							|  |  |  |     enabled(false), | 
					
						
							|  |  |  |     global(false), | 
					
						
							| 
									
										
										
										
											2022-04-08 03:11:33 -04:00
										 |  |  |     speed(0), | 
					
						
							| 
									
										
										
										
											2022-04-07 16:46:48 -04:00
										 |  |  |     param1(0), | 
					
						
							|  |  |  |     param2(0), | 
					
						
							|  |  |  |     param3(0), | 
					
						
							|  |  |  |     param4(0) {} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-06 05:04:18 -04:00
										 |  |  | struct DivInstrumentSoundUnit { | 
					
						
							|  |  |  |   bool useSample; | 
					
						
							|  |  |  |   bool switchRoles; | 
					
						
							|  |  |  |   DivInstrumentSoundUnit(): | 
					
						
							|  |  |  |     useSample(false), | 
					
						
							|  |  |  |     switchRoles(false) {} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:20:10 -04:00
										 |  |  | struct DivInstrumentES5506 { | 
					
						
							|  |  |  |   struct Filter { | 
					
						
							|  |  |  |     enum FilterMode: unsigned char { // filter mode for pole 4,3
 | 
					
						
							| 
									
										
										
										
											2022-08-19 00:55:29 -04:00
										 |  |  |       FILTER_MODE_HPK2_HPK2=0, | 
					
						
							| 
									
										
										
										
											2022-08-18 08:20:10 -04:00
										 |  |  |       FILTER_MODE_HPK2_LPK1, | 
					
						
							|  |  |  |       FILTER_MODE_LPK2_LPK2, | 
					
						
							|  |  |  |       FILTER_MODE_LPK2_LPK1, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     FilterMode mode; | 
					
						
							|  |  |  |     unsigned short k1, k2; | 
					
						
							|  |  |  |     Filter(): | 
					
						
							|  |  |  |       mode(FILTER_MODE_LPK2_LPK1), | 
					
						
							|  |  |  |       k1(0xffff), | 
					
						
							|  |  |  |       k2(0xffff) {} | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   struct Envelope { | 
					
						
							|  |  |  |     unsigned short ecount; | 
					
						
							|  |  |  |     signed char lVRamp, rVRamp; | 
					
						
							|  |  |  |     signed char k1Ramp, k2Ramp; | 
					
						
							|  |  |  |     bool k1Slow, k2Slow; | 
					
						
							|  |  |  |     Envelope(): | 
					
						
							|  |  |  |       ecount(0), | 
					
						
							|  |  |  |       lVRamp(0), | 
					
						
							|  |  |  |       rVRamp(0), | 
					
						
							|  |  |  |       k1Ramp(0), | 
					
						
							|  |  |  |       k2Ramp(0), | 
					
						
							|  |  |  |       k1Slow(false), | 
					
						
							|  |  |  |       k2Slow(false) {} | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   Filter filter; | 
					
						
							|  |  |  |   Envelope envelope; | 
					
						
							| 
									
										
										
										
											2022-08-19 01:49:10 -04:00
										 |  |  |   DivInstrumentES5506(): | 
					
						
							| 
									
										
										
										
											2022-08-19 02:27:21 -04:00
										 |  |  |     filter(Filter()), | 
					
						
							|  |  |  |     envelope(Envelope()) {} | 
					
						
							| 
									
										
										
										
											2022-08-18 08:20:10 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-19 20:42:01 -04:00
										 |  |  | struct DivInstrumentSNES { | 
					
						
							|  |  |  |   enum GainMode: unsigned char { | 
					
						
							|  |  |  |     GAIN_MODE_DIRECT=0, | 
					
						
							|  |  |  |     GAIN_MODE_DEC_LINEAR=4, | 
					
						
							|  |  |  |     GAIN_MODE_DEC_LOG=5, | 
					
						
							|  |  |  |     GAIN_MODE_INC_LINEAR=6, | 
					
						
							|  |  |  |     GAIN_MODE_INC_INVLOG=7 | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   bool useEnv; | 
					
						
							|  |  |  |   GainMode gainMode; | 
					
						
							|  |  |  |   unsigned char gain; | 
					
						
							|  |  |  |   unsigned char a, d, s, r; | 
					
						
							|  |  |  |   DivInstrumentSNES(): | 
					
						
							|  |  |  |     useEnv(true), | 
					
						
							|  |  |  |     gainMode(GAIN_MODE_DIRECT), | 
					
						
							|  |  |  |     gain(127), | 
					
						
							|  |  |  |     a(15), | 
					
						
							|  |  |  |     d(7), | 
					
						
							|  |  |  |     s(7), | 
					
						
							|  |  |  |     r(0) {} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-11 16:08:08 -04:00
										 |  |  | struct DivInstrument { | 
					
						
							|  |  |  |   String name; | 
					
						
							|  |  |  |   bool mode; | 
					
						
							|  |  |  |   DivInstrumentType type; | 
					
						
							|  |  |  |   DivInstrumentFM fm; | 
					
						
							|  |  |  |   DivInstrumentSTD std; | 
					
						
							|  |  |  |   DivInstrumentGB gb; | 
					
						
							|  |  |  |   DivInstrumentC64 c64; | 
					
						
							| 
									
										
										
										
											2022-01-09 03:52:41 -05:00
										 |  |  |   DivInstrumentAmiga amiga; | 
					
						
							| 
									
										
										
										
											2022-03-23 14:53:07 -04:00
										 |  |  |   DivInstrumentN163 n163; | 
					
						
							| 
									
										
										
										
											2022-04-04 05:47:52 -04:00
										 |  |  |   DivInstrumentFDS fds; | 
					
						
							| 
									
										
										
										
											2022-05-05 15:20:36 -04:00
										 |  |  |   DivInstrumentMultiPCM multipcm; | 
					
						
							| 
									
										
										
										
											2022-04-07 16:46:48 -04:00
										 |  |  |   DivInstrumentWaveSynth ws; | 
					
						
							| 
									
										
										
										
											2022-08-06 05:04:18 -04:00
										 |  |  |   DivInstrumentSoundUnit su; | 
					
						
							| 
									
										
										
										
											2022-08-18 08:20:10 -04:00
										 |  |  |   DivInstrumentES5506 es5506; | 
					
						
							| 
									
										
										
										
											2022-08-19 20:42:01 -04:00
										 |  |  |   DivInstrumentSNES snes; | 
					
						
							| 
									
										
										
										
											2022-01-22 00:14:48 -05:00
										 |  |  |    | 
					
						
							| 
									
										
										
										
											2022-03-15 23:05:55 -04:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * save the instrument to a SafeWriter. | 
					
						
							|  |  |  |    * @param w the SafeWriter in question. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2022-01-19 03:28:29 -05:00
										 |  |  |   void putInsData(SafeWriter* w); | 
					
						
							| 
									
										
										
										
											2022-03-15 23:05:55 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * read instrument data in .fui format. | 
					
						
							|  |  |  |    * @param reader the reader. | 
					
						
							|  |  |  |    * @param version the format version. | 
					
						
							|  |  |  |    * @return a DivDataErrors. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2022-01-22 00:14:48 -05:00
										 |  |  |   DivDataErrors readInsData(SafeReader& reader, short version); | 
					
						
							| 
									
										
										
										
											2022-03-15 23:05:55 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * save this instrument to a file. | 
					
						
							|  |  |  |    * @param path file path. | 
					
						
							|  |  |  |    * @return whether it was successful. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2022-01-19 03:28:29 -05:00
										 |  |  |   bool save(const char* path); | 
					
						
							| 
									
										
										
										
											2022-08-13 16:43:13 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * save this instrument to a file in .dmp format. | 
					
						
							|  |  |  |    * @param path file path. | 
					
						
							|  |  |  |    * @return whether it was successful. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   bool saveDMP(const char* path); | 
					
						
							| 
									
										
										
										
											2021-05-16 21:49:54 -04:00
										 |  |  |   DivInstrument(): | 
					
						
							|  |  |  |     name(""), | 
					
						
							| 
									
										
										
										
											2022-03-31 02:51:57 -04:00
										 |  |  |     type(DIV_INS_FM) { | 
					
						
							| 
									
										
										
										
											2021-05-16 21:49:54 -04:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-05-11 16:08:08 -04:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2021-05-15 17:42:48 -04:00
										 |  |  | #endif
 |