| 
									
										
										
										
											2022-02-14 22:12:20 -05:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Furnace Tracker - multi-system chiptune tracker | 
					
						
							| 
									
										
										
										
											2024-01-16 21:26:57 -05:00
										 |  |  |  * Copyright (C) 2021-2024 tildearrow and contributors | 
					
						
							| 
									
										
										
										
											2022-02-14 22:12:20 -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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  | #include "gb.h"
 | 
					
						
							|  |  |  | #include "../engine.h"
 | 
					
						
							| 
									
										
										
										
											2023-07-03 05:06:42 -04:00
										 |  |  | #include "../../ta-log.h"
 | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  | #include <math.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-13 05:09:20 -04:00
										 |  |  | #define rWrite(a,v) if (!skipRegisterWrites) {writes.push(QueuedWrite(a,v)); regPool[(a)&0x7f]=v; if (dumpWrites) {addWrite(a,v);} }
 | 
					
						
							|  |  |  | #define immWrite(a,v) {writes.push(QueuedWrite(a,v)); regPool[(a)&0x7f]=v; if (dumpWrites) {addWrite(a,v);} }
 | 
					
						
							| 
									
										
										
										
											2021-05-26 18:43:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-28 00:55:51 -05:00
										 |  |  | #define CHIP_DIVIDER 16
 | 
					
						
							| 
									
										
										
										
											2021-05-26 18:43:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-02 02:14:42 -05:00
										 |  |  | const char* regCheatSheetGB[]={ | 
					
						
							|  |  |  |   "NR10_Sweep", "10", | 
					
						
							|  |  |  |   "NR11_DutyLen", "11", | 
					
						
							|  |  |  |   "NR12_VolEnv", "12", | 
					
						
							|  |  |  |   "NR13_FreqL", "13", | 
					
						
							|  |  |  |   "NR14_FreqH", "14", | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   "NR21_DutyLen", "16", | 
					
						
							|  |  |  |   "NR22_VolEnv", "17", | 
					
						
							|  |  |  |   "NR23_FreqL", "18", | 
					
						
							|  |  |  |   "NR24_FreqH", "19", | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   "NR30_WaveOn", "1A", | 
					
						
							|  |  |  |   "NR31_Len", "1B", | 
					
						
							|  |  |  |   "NR32_Vol", "1C", | 
					
						
							|  |  |  |   "NR33_FreqL", "1D", | 
					
						
							|  |  |  |   "NR34_FreqH", "1E", | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   "NR41_Len", "20", | 
					
						
							|  |  |  |   "NR42_VolEnv", "21", | 
					
						
							|  |  |  |   "NR43_Freq", "22", | 
					
						
							|  |  |  |   "NR44_Control", "23", | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   "NR50_MasterVol", "24", | 
					
						
							|  |  |  |   "NR51_Toggle", "25", | 
					
						
							|  |  |  |   "NR52_PowerStat", "26", | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   "Wave", "30", | 
					
						
							|  |  |  |   NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-03 18:38:57 -05:00
										 |  |  | const char** DivPlatformGB::getRegisterSheet() { | 
					
						
							|  |  |  |   return regCheatSheetGB; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-02 04:53:37 -05:00
										 |  |  | void DivPlatformGB::acquire(short** buf, size_t len) { | 
					
						
							| 
									
										
										
										
											2023-01-03 01:09:46 -05:00
										 |  |  |   for (size_t i=0; i<len; i++) { | 
					
						
							| 
									
										
										
										
											2024-01-09 23:17:36 -05:00
										 |  |  |     for (int j=0; j<(1<<(outDepth-6)); j++) { | 
					
						
							|  |  |  |       if (!writes.empty()) { | 
					
						
							|  |  |  |         QueuedWrite& w=writes.front(); | 
					
						
							|  |  |  |         GB_apu_write(gb,w.addr,w.val); | 
					
						
							|  |  |  |         writes.pop(); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-08-11 01:46:15 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-09 23:17:36 -05:00
										 |  |  |       GB_advance_cycles(gb,16); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-01-02 04:53:37 -05:00
										 |  |  |     buf[0][i]=gb->apu_output.final_sample.left; | 
					
						
							|  |  |  |     buf[1][i]=gb->apu_output.final_sample.right; | 
					
						
							| 
									
										
										
										
											2022-04-30 19:33:12 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (int i=0; i<4; i++) { | 
					
						
							| 
									
										
										
										
											2023-06-18 05:27:22 -04:00
										 |  |  |       oscBuf[i]->data[oscBuf[i]->needle++]=(gb->apu_output.current_sample[i].left+gb->apu_output.current_sample[i].right)<<6; | 
					
						
							| 
									
										
										
										
											2022-04-30 19:33:12 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-06 05:21:42 -05:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-27 14:30:37 -04:00
										 |  |  | void DivPlatformGB::updateWave() { | 
					
						
							| 
									
										
										
										
											2024-01-09 23:17:36 -05:00
										 |  |  |   if (doubleWave) { | 
					
						
							|  |  |  |     rWrite(0x1a,0x40); // select 1 -> write to bank 0
 | 
					
						
							|  |  |  |     for (int i=0; i<16; i++) { | 
					
						
							|  |  |  |       int nibble1=ws.output[((i<<1)+antiClickWavePos)&63]; | 
					
						
							|  |  |  |       int nibble2=ws.output[((1+(i<<1))+antiClickWavePos)&63]; | 
					
						
							|  |  |  |       if (invertWave) { | 
					
						
							|  |  |  |         nibble1^=15; | 
					
						
							|  |  |  |         nibble2^=15; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       rWrite(0x30+i,(nibble1<<4)|nibble2); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     rWrite(0x1a,0); // select 0 -> write to bank 1
 | 
					
						
							|  |  |  |     for (int i=0; i<16; i++) { | 
					
						
							|  |  |  |       int nibble1=ws.output[((32+(i<<1))+antiClickWavePos)&63]; | 
					
						
							|  |  |  |       int nibble2=ws.output[((33+(i<<1))+antiClickWavePos)&63]; | 
					
						
							|  |  |  |       if (invertWave) { | 
					
						
							|  |  |  |         nibble1^=15; | 
					
						
							|  |  |  |         nibble2^=15; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       rWrite(0x30+i,(nibble1<<4)|nibble2); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     antiClickWavePos&=63; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     rWrite(0x1a,extendWave?0x40:0); | 
					
						
							|  |  |  |     for (int i=0; i<16; i++) { | 
					
						
							|  |  |  |       int nibble1=ws.output[((i<<1)+antiClickWavePos)&31]; | 
					
						
							|  |  |  |       int nibble2=ws.output[((1+(i<<1))+antiClickWavePos)&31]; | 
					
						
							|  |  |  |       if (invertWave) { | 
					
						
							|  |  |  |         nibble1^=15; | 
					
						
							|  |  |  |         nibble2^=15; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       rWrite(0x30+i,(nibble1<<4)|nibble2); | 
					
						
							| 
									
										
										
										
											2023-05-04 03:18:56 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-01-09 23:17:36 -05:00
										 |  |  |     antiClickWavePos&=31; | 
					
						
							| 
									
										
										
										
											2021-05-27 14:30:37 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-18 03:25:42 -05:00
										 |  |  | static unsigned char chanMuteMask[4]={ | 
					
						
							|  |  |  |   0xee, 0xdd, 0xbb, 0x77 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | unsigned char DivPlatformGB::procMute() { | 
					
						
							|  |  |  |   return lastPan&(isMuted[0]?chanMuteMask[0]:0xff) | 
					
						
							|  |  |  |                 &(isMuted[1]?chanMuteMask[1]:0xff) | 
					
						
							|  |  |  |                 &(isMuted[2]?chanMuteMask[2]:0xff) | 
					
						
							|  |  |  |                 &(isMuted[3]?chanMuteMask[3]:0xff); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-27 14:30:37 -04:00
										 |  |  | static unsigned char gbVolMap[16]={ | 
					
						
							| 
									
										
										
										
											2021-05-28 02:26:57 -04:00
										 |  |  |   0x00, 0x00, 0x00, 0x00, | 
					
						
							|  |  |  |   0x60, 0x60, 0x60, 0x60, | 
					
						
							| 
									
										
										
										
											2021-05-27 14:30:37 -04:00
										 |  |  |   0x40, 0x40, 0x40, 0x40, | 
					
						
							|  |  |  |   0x20, 0x20, 0x20, 0x20 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-09 23:17:36 -05:00
										 |  |  | static unsigned char gbVolMapEx[16]={ | 
					
						
							|  |  |  |   0x00, 0x00, 0x00, 0x00, | 
					
						
							|  |  |  |   0x60, 0x60, 0x60, 0x60, | 
					
						
							|  |  |  |   0x40, 0x40, 0x40, 0x40, | 
					
						
							|  |  |  |   0xa0, 0xa0, 0x20, 0x20 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-28 00:03:10 -04:00
										 |  |  | static unsigned char noiseTable[256]={ | 
					
						
							|  |  |  |   0, | 
					
						
							|  |  |  |   0xf7, 0xf6, 0xf5, 0xf4, | 
					
						
							|  |  |  |   0xe7, 0xe6, 0xe5, 0xe4, | 
					
						
							|  |  |  |   0xd7, 0xd6, 0xd5, 0xd4, | 
					
						
							|  |  |  |   0xc7, 0xc6, 0xc5, 0xc4, | 
					
						
							|  |  |  |   0xb7, 0xb6, 0xb5, 0xb4, | 
					
						
							|  |  |  |   0xa7, 0xa6, 0xa5, 0xa4, | 
					
						
							|  |  |  |   0x97, 0x96, 0x95, 0x94, | 
					
						
							|  |  |  |   0x87, 0x86, 0x85, 0x84, | 
					
						
							|  |  |  |   0x77, 0x76, 0x75, 0x74, | 
					
						
							|  |  |  |   0x67, 0x66, 0x65, 0x64, | 
					
						
							|  |  |  |   0x57, 0x56, 0x55, 0x54, | 
					
						
							|  |  |  |   0x47, 0x46, 0x45, 0x44, | 
					
						
							|  |  |  |   0x37, 0x36, 0x35, 0x34, | 
					
						
							|  |  |  |   0x27, 0x26, 0x25, 0x24, | 
					
						
							|  |  |  |   0x17, 0x16, 0x15, 0x14, | 
					
						
							|  |  |  |   0x07, 0x06, 0x05, 0x04, | 
					
						
							|  |  |  |   0x03, 0x02, 0x01, 0x00, | 
					
						
							|  |  |  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
					
						
							|  |  |  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
					
						
							|  |  |  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
					
						
							|  |  |  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
					
						
							|  |  |  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
					
						
							|  |  |  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
					
						
							|  |  |  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
					
						
							|  |  |  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-15 16:01:11 -04:00
										 |  |  | void DivPlatformGB::tick(bool sysTick) { | 
					
						
							| 
									
										
										
										
											2022-08-03 20:17:18 -04:00
										 |  |  |   if (antiClickEnabled && sysTick && chan[2].freq>0) { | 
					
						
							|  |  |  |     antiClickPeriodCount+=((chipClock>>1)/MAX(parent->getCurHz(),1.0f)); | 
					
						
							|  |  |  |     antiClickWavePos+=antiClickPeriodCount/chan[2].freq; | 
					
						
							|  |  |  |     antiClickPeriodCount%=chan[2].freq; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |   for (int i=0; i<4; i++) { | 
					
						
							|  |  |  |     chan[i].std.next(); | 
					
						
							| 
									
										
										
										
											2022-08-10 17:27:29 -04:00
										 |  |  |     if (chan[i].softEnv) { | 
					
						
							|  |  |  |       if (chan[i].std.vol.had) { | 
					
						
							|  |  |  |         chan[i].outVol=VOL_SCALE_LINEAR(chan[i].vol&15,MIN(15,chan[i].std.vol.val),15); | 
					
						
							|  |  |  |         if (chan[i].outVol<0) chan[i].outVol=0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-11 02:34:18 -04:00
										 |  |  |         if (i==2) { | 
					
						
							| 
									
										
										
										
											2024-01-09 23:17:36 -05:00
										 |  |  |           rWrite(16+i*5+2,(extendWave?gbVolMapEx:gbVolMap)[chan[i].outVol]); | 
					
						
							| 
									
										
										
										
											2022-08-11 06:04:35 -04:00
										 |  |  |           chan[i].soundLen=64; | 
					
						
							| 
									
										
										
										
											2022-08-11 02:34:18 -04:00
										 |  |  |         } else { | 
					
						
							|  |  |  |           chan[i].envLen=0; | 
					
						
							|  |  |  |           chan[i].envDir=1; | 
					
						
							|  |  |  |           chan[i].envVol=chan[i].outVol; | 
					
						
							|  |  |  |           chan[i].soundLen=64; | 
					
						
							| 
									
										
										
										
											2022-08-11 02:24:53 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-11 02:34:18 -04:00
										 |  |  |           if (!chan[i].keyOn) chan[i].killIt=true; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-08-10 17:27:29 -04:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-12-17 02:43:07 -05:00
										 |  |  |     if (NEW_ARP_STRAT && i!=3) { | 
					
						
							| 
									
										
										
										
											2022-12-17 01:21:08 -05:00
										 |  |  |       chan[i].handleArp(); | 
					
						
							|  |  |  |     } else if (chan[i].std.arp.had) { | 
					
						
							| 
									
										
										
										
											2021-05-28 00:03:10 -04:00
										 |  |  |       if (i==3) { // noise
 | 
					
						
							| 
									
										
										
										
											2022-08-22 16:59:45 -04:00
										 |  |  |         chan[i].baseFreq=parent->calcArp(chan[i].note,chan[i].std.arp.val,24); | 
					
						
							| 
									
										
										
										
											2021-05-28 03:02:54 -04:00
										 |  |  |         if (chan[i].baseFreq>255) chan[i].baseFreq=255; | 
					
						
							|  |  |  |         if (chan[i].baseFreq<0) chan[i].baseFreq=0; | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2022-10-08 00:37:56 -04:00
										 |  |  |         if (!chan[i].inPorta) { | 
					
						
							|  |  |  |           chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val,24)); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |       } | 
					
						
							|  |  |  |       chan[i].freqChanged=true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-04-10 01:01:55 -04:00
										 |  |  |     if (chan[i].std.duty.had) { | 
					
						
							|  |  |  |       chan[i].duty=chan[i].std.duty.val; | 
					
						
							| 
									
										
										
										
											2021-05-27 14:30:37 -04:00
										 |  |  |       if (i!=2) { | 
					
						
							| 
									
										
										
										
											2022-08-07 01:22:03 -04:00
										 |  |  |         rWrite(16+i*5+1,((chan[i].duty&3)<<6)|(63-(chan[i].soundLen&63))); | 
					
						
							| 
									
										
										
										
											2022-08-10 17:27:29 -04:00
										 |  |  |       } else if (!chan[i].softEnv) { | 
					
						
							| 
									
										
										
										
											2022-02-06 01:56:50 -05:00
										 |  |  |         if (parent->song.waveDutyIsVol) { | 
					
						
							| 
									
										
										
										
											2024-01-09 23:17:36 -05:00
										 |  |  |           rWrite(16+i*5+2,(extendWave?gbVolMapEx:gbVolMap)[(chan[i].std.duty.val&3)<<2]); | 
					
						
							| 
									
										
										
										
											2022-02-06 01:56:50 -05:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-05-27 14:30:37 -04:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-04-10 01:01:55 -04:00
										 |  |  |     if (i==2 && chan[i].std.wave.had) { | 
					
						
							|  |  |  |       if (chan[i].wave!=chan[i].std.wave.val || ws.activeChanged()) { | 
					
						
							|  |  |  |         chan[i].wave=chan[i].std.wave.val; | 
					
						
							| 
									
										
										
										
											2022-04-08 03:11:33 -04:00
										 |  |  |         ws.changeWave1(chan[i].wave); | 
					
						
							|  |  |  |         if (!chan[i].keyOff) chan[i].keyOn=true; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-04-17 15:15:57 -04:00
										 |  |  |     if (chan[i].std.panL.had) { | 
					
						
							|  |  |  |       lastPan&=~(0x11<<i); | 
					
						
							|  |  |  |       lastPan|=((chan[i].std.panL.val&1)<<i)|((chan[i].std.panL.val&2)<<(i+3)); | 
					
						
							|  |  |  |       rWrite(0x25,procMute()); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-04-16 02:39:40 -04:00
										 |  |  |     if (chan[i].std.pitch.had) { | 
					
						
							| 
									
										
										
										
											2022-04-28 02:31:16 -04:00
										 |  |  |       if (chan[i].std.pitch.mode) { | 
					
						
							|  |  |  |         chan[i].pitch2+=chan[i].std.pitch.val; | 
					
						
							| 
									
										
										
										
											2022-05-22 23:47:40 -04:00
										 |  |  |         CLAMP_VAR(chan[i].pitch2,-32768,32767); | 
					
						
							| 
									
										
										
										
											2022-04-28 02:31:16 -04:00
										 |  |  |       } else { | 
					
						
							|  |  |  |         chan[i].pitch2=chan[i].std.pitch.val; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-04-16 02:39:40 -04:00
										 |  |  |       chan[i].freqChanged=true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-04-15 04:16:14 -04:00
										 |  |  |     if (chan[i].std.phaseReset.had) { | 
					
						
							|  |  |  |       if (chan[i].std.phaseReset.val==1) { | 
					
						
							|  |  |  |         chan[i].keyOn=true; | 
					
						
							| 
									
										
										
										
											2022-08-06 01:39:09 -04:00
										 |  |  |         if (i==2) { | 
					
						
							|  |  |  |           antiClickWavePos=0; | 
					
						
							|  |  |  |           antiClickPeriodCount=0; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-04-15 04:16:14 -04:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-04-08 03:11:33 -04:00
										 |  |  |     if (i==2) { | 
					
						
							|  |  |  |       if (chan[i].active) { | 
					
						
							|  |  |  |         if (ws.tick()) { | 
					
						
							| 
									
										
										
										
											2021-05-27 17:47:09 -04:00
										 |  |  |           updateWave(); | 
					
						
							|  |  |  |           if (!chan[i].keyOff) chan[i].keyOn=true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-05-27 14:30:37 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-10 02:55:44 -04:00
										 |  |  |     // run hardware sequence
 | 
					
						
							|  |  |  |     if (chan[i].active) { | 
					
						
							|  |  |  |       if (--chan[i].hwSeqDelay<=0) { | 
					
						
							|  |  |  |         chan[i].hwSeqDelay=0; | 
					
						
							|  |  |  |         DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_GB); | 
					
						
							|  |  |  |         int hwSeqCount=0; | 
					
						
							|  |  |  |         while (chan[i].hwSeqPos<ins->gb.hwSeqLen && hwSeqCount<4) { | 
					
						
							|  |  |  |           bool leave=false; | 
					
						
							|  |  |  |           unsigned short data=ins->gb.hwSeq[chan[i].hwSeqPos].data; | 
					
						
							|  |  |  |           switch (ins->gb.hwSeq[chan[i].hwSeqPos].cmd) { | 
					
						
							|  |  |  |             case DivInstrumentGB::DIV_GB_HWCMD_ENVELOPE: | 
					
						
							| 
									
										
										
										
											2022-08-10 17:27:29 -04:00
										 |  |  |               if (!chan[i].softEnv) { | 
					
						
							|  |  |  |                 chan[i].envLen=data&7; | 
					
						
							|  |  |  |                 chan[i].envDir=(data&8)?1:0; | 
					
						
							|  |  |  |                 chan[i].envVol=(data>>4)&15; | 
					
						
							|  |  |  |                 chan[i].soundLen=data>>8; | 
					
						
							|  |  |  |                 chan[i].keyOn=true; | 
					
						
							|  |  |  |               } | 
					
						
							| 
									
										
										
										
											2022-08-10 02:55:44 -04:00
										 |  |  |               break; | 
					
						
							|  |  |  |             case DivInstrumentGB::DIV_GB_HWCMD_SWEEP: | 
					
						
							|  |  |  |               chan[i].sweep=data; | 
					
						
							|  |  |  |               chan[i].sweepChanged=true; | 
					
						
							|  |  |  |               break; | 
					
						
							|  |  |  |             case DivInstrumentGB::DIV_GB_HWCMD_WAIT: | 
					
						
							| 
									
										
										
										
											2023-07-25 02:51:22 -04:00
										 |  |  |               chan[i].hwSeqDelay=(data+1)*parent->tickMult; | 
					
						
							| 
									
										
										
										
											2022-08-10 02:55:44 -04:00
										 |  |  |               leave=true; | 
					
						
							|  |  |  |               break; | 
					
						
							|  |  |  |             case DivInstrumentGB::DIV_GB_HWCMD_WAIT_REL: | 
					
						
							|  |  |  |               if (!chan[i].released) { | 
					
						
							|  |  |  |                 chan[i].hwSeqPos--; | 
					
						
							|  |  |  |                 leave=true; | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |               break; | 
					
						
							|  |  |  |             case DivInstrumentGB::DIV_GB_HWCMD_LOOP: | 
					
						
							|  |  |  |               chan[i].hwSeqPos=data-1; | 
					
						
							|  |  |  |               break; | 
					
						
							|  |  |  |             case DivInstrumentGB::DIV_GB_HWCMD_LOOP_REL: | 
					
						
							|  |  |  |               if (!chan[i].released) { | 
					
						
							|  |  |  |                 chan[i].hwSeqPos=data-1; | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |               break; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           chan[i].hwSeqPos++; | 
					
						
							|  |  |  |           if (leave) break; | 
					
						
							|  |  |  |           hwSeqCount++; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-28 02:26:57 -04:00
										 |  |  |     if (chan[i].sweepChanged) { | 
					
						
							|  |  |  |       chan[i].sweepChanged=false; | 
					
						
							|  |  |  |       if (i==0) { | 
					
						
							|  |  |  |         rWrite(16+i*5,chan[i].sweep); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-10 02:55:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-27 14:30:37 -04:00
										 |  |  |     if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { | 
					
						
							| 
									
										
										
										
											2021-05-28 00:03:10 -04:00
										 |  |  |       if (i==3) { // noise
 | 
					
						
							| 
									
										
										
										
											2023-01-12 18:36:13 -05:00
										 |  |  |         int ntPos=chan[i].baseFreq+chan[i].pitch2; | 
					
						
							| 
									
										
										
										
											2022-02-06 01:56:50 -05:00
										 |  |  |         if (ntPos<0) ntPos=0; | 
					
						
							|  |  |  |         if (ntPos>255) ntPos=255; | 
					
						
							|  |  |  |         chan[i].freq=noiseTable[ntPos]; | 
					
						
							| 
									
										
										
										
											2021-05-28 00:03:10 -04:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2022-12-17 02:07:24 -05:00
										 |  |  |         chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER); | 
					
						
							| 
									
										
										
										
											2021-05-28 03:49:01 -04:00
										 |  |  |         if (chan[i].freq>2047) chan[i].freq=2047; | 
					
						
							| 
									
										
										
										
											2023-01-12 17:59:40 -05:00
										 |  |  |         if (chan[i].freq<1) chan[i].freq=1; | 
					
						
							| 
									
										
										
										
											2021-05-28 00:03:10 -04:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-05-27 14:30:37 -04:00
										 |  |  |       if (chan[i].keyOn) { | 
					
						
							|  |  |  |         if (i==2) { // wave
 | 
					
						
							| 
									
										
										
										
											2023-07-03 05:06:42 -04:00
										 |  |  |           rWrite(16+i*5,0x00); | 
					
						
							| 
									
										
										
										
											2024-01-09 23:17:36 -05:00
										 |  |  |           rWrite(16+i*5,doubleWave?0xa0:0x80); | 
					
						
							|  |  |  |           rWrite(16+i*5+2,(extendWave?gbVolMapEx:gbVolMap)[chan[i].outVol]); | 
					
						
							| 
									
										
										
										
											2021-05-27 14:30:37 -04:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2022-08-07 01:22:03 -04:00
										 |  |  |           rWrite(16+i*5+1,((chan[i].duty&3)<<6)|(63-(chan[i].soundLen&63))); | 
					
						
							| 
									
										
										
										
											2022-08-10 18:02:45 -04:00
										 |  |  |           rWrite(16+i*5+2,((chan[i].envVol<<4))|(chan[i].envLen&7)|((chan[i].envDir&1)<<3)); | 
					
						
							| 
									
										
										
										
											2022-08-11 02:24:53 -04:00
										 |  |  |           chan[i].lastKill=chan[i].envVol; | 
					
						
							| 
									
										
										
										
											2021-05-27 14:30:37 -04:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (chan[i].keyOff) { | 
					
						
							|  |  |  |         if (i==2) { | 
					
						
							|  |  |  |           rWrite(16+i*5+2,0); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           rWrite(16+i*5+2,8); | 
					
						
							| 
									
										
										
										
											2021-05-26 18:43:14 -04:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-05-28 00:03:10 -04:00
										 |  |  |       if (i==3) { // noise
 | 
					
						
							| 
									
										
										
										
											2021-05-28 02:26:57 -04:00
										 |  |  |         rWrite(16+i*5+3,(chan[i].freq&0xff)|(chan[i].duty?8:0)); | 
					
						
							| 
									
										
										
										
											2022-08-07 01:22:03 -04:00
										 |  |  |         rWrite(16+i*5+4,((chan[i].keyOn||chan[i].keyOff)?0x80:0x00)|((chan[i].soundLen<64)<<6)); | 
					
						
							| 
									
										
										
										
											2021-05-28 00:03:10 -04:00
										 |  |  |       } else { | 
					
						
							|  |  |  |         rWrite(16+i*5+3,(2048-chan[i].freq)&0xff); | 
					
						
							| 
									
										
										
										
											2023-07-07 03:21:13 -04:00
										 |  |  |         rWrite(16+i*5+4,(((2048-chan[i].freq)>>8)&7)|((chan[i].keyOn||(chan[i].keyOff && i!=2))?0x80:0x00)|((chan[i].soundLen<63)<<6)); | 
					
						
							| 
									
										
										
										
											2021-05-28 00:03:10 -04:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-10-02 01:06:06 -04:00
										 |  |  |       if (enoughAlready) { // more compat garbage
 | 
					
						
							|  |  |  |         rWrite(16+i*5+1,((chan[i].duty&3)<<6)|(63-(chan[i].soundLen&63))); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-05-27 14:30:37 -04:00
										 |  |  |       if (chan[i].keyOn) chan[i].keyOn=false; | 
					
						
							|  |  |  |       if (chan[i].keyOff) chan[i].keyOff=false; | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |       chan[i].freqChanged=false; | 
					
						
							| 
									
										
										
										
											2022-08-15 23:36:26 -04:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (chan[i].killIt) { | 
					
						
							|  |  |  |       if (i!=2) { | 
					
						
							|  |  |  |         //rWrite(16+i*5+2,8);
 | 
					
						
							|  |  |  |         int killDelta=chan[i].lastKill-chan[i].outVol+1; | 
					
						
							|  |  |  |         if (killDelta<0) killDelta+=16; | 
					
						
							|  |  |  |         chan[i].lastKill=chan[i].outVol; | 
					
						
							| 
									
										
										
										
											2022-08-11 02:24:53 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-15 23:36:26 -04:00
										 |  |  |         if (killDelta!=1) { | 
					
						
							|  |  |  |           rWrite(16+i*5+2,((chan[i].envVol<<4))|8); | 
					
						
							|  |  |  |           for (int j=0; j<killDelta; j++) { | 
					
						
							|  |  |  |             rWrite(16+i*5+2,0x09); | 
					
						
							|  |  |  |             rWrite(16+i*5+2,0x11); | 
					
						
							|  |  |  |             rWrite(16+i*5+2,0x08); | 
					
						
							| 
									
										
										
										
											2022-08-11 02:24:53 -04:00
										 |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-08-15 23:36:26 -04:00
										 |  |  |       chan[i].killIt=false; | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-15 00:07:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     chan[i].soManyHacksToMakeItDefleCompatible=false; | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-18 03:25:42 -05:00
										 |  |  | void DivPlatformGB::muteChannel(int ch, bool mute) { | 
					
						
							|  |  |  |   isMuted[ch]=mute; | 
					
						
							|  |  |  |   rWrite(0x25,procMute()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  | int DivPlatformGB::dispatch(DivCommand c) { | 
					
						
							|  |  |  |   switch (c.cmd) { | 
					
						
							| 
									
										
										
										
											2022-04-08 03:11:33 -04:00
										 |  |  |     case DIV_CMD_NOTE_ON: { | 
					
						
							| 
									
										
										
										
											2022-04-21 03:24:06 -04:00
										 |  |  |       DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_GB); | 
					
						
							| 
									
										
										
										
											2022-01-19 00:01:34 -05:00
										 |  |  |       if (c.value!=DIV_NOTE_NULL) { | 
					
						
							|  |  |  |         if (c.chan==3) { // noise
 | 
					
						
							|  |  |  |           chan[c.chan].baseFreq=c.value; | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2022-01-28 00:55:51 -05:00
										 |  |  |           chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); | 
					
						
							| 
									
										
										
										
											2022-01-19 00:01:34 -05:00
										 |  |  |         } | 
					
						
							|  |  |  |         chan[c.chan].freqChanged=true; | 
					
						
							|  |  |  |         chan[c.chan].note=c.value; | 
					
						
							| 
									
										
										
										
											2021-05-28 00:03:10 -04:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |       chan[c.chan].active=true; | 
					
						
							| 
									
										
										
										
											2021-05-26 18:43:14 -04:00
										 |  |  |       chan[c.chan].keyOn=true; | 
					
						
							| 
									
										
										
										
											2022-08-10 02:55:44 -04:00
										 |  |  |       chan[c.chan].hwSeqPos=0; | 
					
						
							|  |  |  |       chan[c.chan].hwSeqDelay=0; | 
					
						
							|  |  |  |       chan[c.chan].released=false; | 
					
						
							| 
									
										
										
										
											2022-08-10 17:27:29 -04:00
										 |  |  |       chan[c.chan].softEnv=ins->gb.softEnv; | 
					
						
							| 
									
										
										
										
											2022-04-28 02:31:16 -04:00
										 |  |  |       chan[c.chan].macroInit(ins); | 
					
						
							| 
									
										
										
										
											2022-04-08 03:11:33 -04:00
										 |  |  |       if (c.chan==2) { | 
					
						
							| 
									
										
										
										
											2024-01-09 23:17:36 -05:00
										 |  |  |         doubleWave=extendWave&&ins->gb.doubleWave; | 
					
						
							| 
									
										
										
										
											2022-04-08 03:11:33 -04:00
										 |  |  |         if (chan[c.chan].wave<0) { | 
					
						
							|  |  |  |           chan[c.chan].wave=0; | 
					
						
							|  |  |  |           ws.changeWave1(chan[c.chan].wave); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-01-09 23:17:36 -05:00
										 |  |  |         ws.init(ins,doubleWave?64:32,15,chan[c.chan].insChanged); | 
					
						
							|  |  |  |         if (doubleWave!=lastDoubleWave) { | 
					
						
							|  |  |  |           ws.changeWave1(chan[c.chan].wave); | 
					
						
							|  |  |  |           lastDoubleWave=doubleWave; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-08-07 01:37:35 -04:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-08-11 02:24:53 -04:00
										 |  |  |       if ((chan[c.chan].insChanged || ins->gb.alwaysInit) && !chan[c.chan].softEnv) { | 
					
						
							| 
									
										
										
										
											2022-08-15 00:28:15 -04:00
										 |  |  |         if (!chan[c.chan].soManyHacksToMakeItDefleCompatible && c.chan!=2) { | 
					
						
							| 
									
										
										
										
											2022-08-15 00:07:19 -04:00
										 |  |  |           chan[c.chan].envVol=ins->gb.envVol; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-08-07 01:22:03 -04:00
										 |  |  |         chan[c.chan].envLen=ins->gb.envLen; | 
					
						
							|  |  |  |         chan[c.chan].envDir=ins->gb.envDir; | 
					
						
							|  |  |  |         chan[c.chan].soundLen=ins->gb.soundLen; | 
					
						
							| 
									
										
										
										
											2022-08-15 00:28:15 -04:00
										 |  |  |         if (!chan[c.chan].soManyHacksToMakeItDefleCompatible && c.chan!=2) { | 
					
						
							| 
									
										
										
										
											2022-08-15 00:07:19 -04:00
										 |  |  |           chan[c.chan].vol=chan[c.chan].envVol; | 
					
						
							|  |  |  |           chan[c.chan].outVol=chan[c.chan].envVol; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-07-08 18:08:08 -04:00
										 |  |  |       } else if (chan[c.chan].softEnv && c.chan!=2) { | 
					
						
							|  |  |  |         if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) { | 
					
						
							|  |  |  |           chan[c.chan].outVol=chan[c.chan].vol; | 
					
						
							|  |  |  |           chan[c.chan].envVol=chan[c.chan].outVol; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         chan[c.chan].envLen=0; | 
					
						
							|  |  |  |         chan[c.chan].envDir=1; | 
					
						
							|  |  |  |         chan[c.chan].soundLen=64; | 
					
						
							| 
									
										
										
										
											2022-04-08 03:11:33 -04:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-08-11 06:04:35 -04:00
										 |  |  |       if (c.chan==2 && chan[c.chan].softEnv) { | 
					
						
							|  |  |  |         chan[c.chan].soundLen=64; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-04-08 03:11:33 -04:00
										 |  |  |       chan[c.chan].insChanged=false; | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2022-04-08 03:11:33 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |     case DIV_CMD_NOTE_OFF: | 
					
						
							|  |  |  |       chan[c.chan].active=false; | 
					
						
							| 
									
										
										
										
											2021-05-26 18:43:14 -04:00
										 |  |  |       chan[c.chan].keyOff=true; | 
					
						
							| 
									
										
										
										
											2022-08-10 02:55:44 -04:00
										 |  |  |       chan[c.chan].hwSeqPos=0; | 
					
						
							|  |  |  |       chan[c.chan].hwSeqDelay=0; | 
					
						
							| 
									
										
										
										
											2022-04-28 02:31:16 -04:00
										 |  |  |       chan[c.chan].macroInit(NULL); | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2022-02-08 13:11:04 -05:00
										 |  |  |     case DIV_CMD_NOTE_OFF_ENV: | 
					
						
							|  |  |  |     case DIV_CMD_ENV_RELEASE: | 
					
						
							|  |  |  |       chan[c.chan].std.release(); | 
					
						
							| 
									
										
										
										
											2022-08-10 02:55:44 -04:00
										 |  |  |       chan[c.chan].released=true; | 
					
						
							| 
									
										
										
										
											2022-02-08 13:11:04 -05:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |     case DIV_CMD_INSTRUMENT: | 
					
						
							| 
									
										
										
										
											2022-01-17 18:01:40 -05:00
										 |  |  |       if (chan[c.chan].ins!=c.value || c.value2==1) { | 
					
						
							| 
									
										
										
										
											2021-05-28 02:26:57 -04:00
										 |  |  |         chan[c.chan].ins=c.value; | 
					
						
							| 
									
										
										
										
											2022-04-08 03:11:33 -04:00
										 |  |  |         chan[c.chan].insChanged=true; | 
					
						
							| 
									
										
										
										
											2021-05-28 02:26:57 -04:00
										 |  |  |         if (c.chan!=2) { | 
					
						
							| 
									
										
										
										
											2022-04-21 03:24:06 -04:00
										 |  |  |           DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_GB); | 
					
						
							| 
									
										
										
										
											2022-08-10 17:27:29 -04:00
										 |  |  |           if (!ins->gb.softEnv) { | 
					
						
							|  |  |  |             chan[c.chan].envVol=ins->gb.envVol; | 
					
						
							|  |  |  |             chan[c.chan].envLen=ins->gb.envLen; | 
					
						
							|  |  |  |             chan[c.chan].envDir=ins->gb.envDir; | 
					
						
							|  |  |  |             chan[c.chan].soundLen=ins->gb.soundLen; | 
					
						
							|  |  |  |             chan[c.chan].vol=chan[c.chan].envVol; | 
					
						
							| 
									
										
										
										
											2022-08-10 18:02:45 -04:00
										 |  |  |             chan[c.chan].outVol=chan[c.chan].vol; | 
					
						
							| 
									
										
										
										
											2022-08-10 17:27:29 -04:00
										 |  |  |             if (parent->song.gbInsAffectsEnvelope) { | 
					
						
							|  |  |  |               rWrite(16+c.chan*5+2,((chan[c.chan].vol<<4))|(chan[c.chan].envLen&7)|((chan[c.chan].envDir&1)<<3)); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-03-26 23:15:15 -04:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2021-05-28 02:26:57 -04:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-05-27 14:30:37 -04:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |       break; | 
					
						
							|  |  |  |     case DIV_CMD_VOLUME: | 
					
						
							| 
									
										
										
										
											2021-05-28 01:36:25 -04:00
										 |  |  |       chan[c.chan].vol=c.value; | 
					
						
							| 
									
										
										
										
											2022-08-10 18:02:45 -04:00
										 |  |  |       chan[c.chan].outVol=c.value; | 
					
						
							| 
									
										
										
										
											2021-05-28 01:36:25 -04:00
										 |  |  |       if (c.chan==2) { | 
					
						
							| 
									
										
										
										
											2024-01-09 23:17:36 -05:00
										 |  |  |         rWrite(16+c.chan*5+2,(extendWave?gbVolMapEx:gbVolMap)[chan[c.chan].outVol]); | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-08-11 00:53:47 -04:00
										 |  |  |       if (!chan[c.chan].softEnv) { | 
					
						
							|  |  |  |         chan[c.chan].envVol=chan[c.chan].vol; | 
					
						
							| 
									
										
										
										
											2022-08-15 00:07:19 -04:00
										 |  |  |         chan[c.chan].soManyHacksToMakeItDefleCompatible=true; | 
					
						
							| 
									
										
										
										
											2022-08-11 02:34:18 -04:00
										 |  |  |       } else if (c.chan!=2) { | 
					
						
							| 
									
										
										
										
											2022-09-26 02:48:09 -04:00
										 |  |  |         if (chan[c.chan].std.vol.will && !chan[c.chan].std.vol.finished) { | 
					
						
							|  |  |  |           chan[c.chan].outVol=VOL_SCALE_LINEAR(chan[c.chan].vol&15,MIN(15,chan[c.chan].std.vol.val),15); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         chan[c.chan].envVol=chan[c.chan].outVol; | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2023-08-17 19:28:48 -04:00
										 |  |  |         if (!chan[c.chan].keyOn && chan[c.chan].active) chan[c.chan].killIt=true; | 
					
						
							| 
									
										
										
										
											2022-08-11 02:34:18 -04:00
										 |  |  |         chan[c.chan].freqChanged=true; | 
					
						
							| 
									
										
										
										
											2022-08-11 00:53:47 -04:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |       break; | 
					
						
							|  |  |  |     case DIV_CMD_GET_VOLUME: | 
					
						
							| 
									
										
										
										
											2021-05-26 18:43:14 -04:00
										 |  |  |       return chan[c.chan].vol; | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |       break; | 
					
						
							|  |  |  |     case DIV_CMD_PITCH: | 
					
						
							|  |  |  |       chan[c.chan].pitch=c.value; | 
					
						
							|  |  |  |       chan[c.chan].freqChanged=true; | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2021-05-28 01:36:25 -04:00
										 |  |  |     case DIV_CMD_WAVE: | 
					
						
							|  |  |  |       if (c.chan!=2) break; | 
					
						
							|  |  |  |       chan[c.chan].wave=c.value; | 
					
						
							| 
									
										
										
										
											2022-04-08 03:11:33 -04:00
										 |  |  |       ws.changeWave1(chan[c.chan].wave); | 
					
						
							| 
									
										
										
										
											2023-07-07 03:25:32 -04:00
										 |  |  |       if (chan[c.chan].active) { | 
					
						
							|  |  |  |         chan[c.chan].keyOn=true; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-05-28 01:36:25 -04:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |     case DIV_CMD_NOTE_PORTA: { | 
					
						
							| 
									
										
										
										
											2022-01-28 00:55:51 -05:00
										 |  |  |       int destFreq=NOTE_PERIODIC(c.value2); | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |       bool return2=false; | 
					
						
							|  |  |  |       if (destFreq>chan[c.chan].baseFreq) { | 
					
						
							|  |  |  |         chan[c.chan].baseFreq+=c.value; | 
					
						
							|  |  |  |         if (chan[c.chan].baseFreq>=destFreq) { | 
					
						
							|  |  |  |           chan[c.chan].baseFreq=destFreq; | 
					
						
							|  |  |  |           return2=true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         chan[c.chan].baseFreq-=c.value; | 
					
						
							|  |  |  |         if (chan[c.chan].baseFreq<=destFreq) { | 
					
						
							|  |  |  |           chan[c.chan].baseFreq=destFreq; | 
					
						
							|  |  |  |           return2=true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       chan[c.chan].freqChanged=true; | 
					
						
							| 
									
										
										
										
											2021-05-28 03:30:09 -04:00
										 |  |  |       if (return2) { | 
					
						
							|  |  |  |         chan[c.chan].inPorta=false; | 
					
						
							|  |  |  |         return 2; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case DIV_CMD_STD_NOISE_MODE: | 
					
						
							| 
									
										
										
										
											2021-05-28 02:26:57 -04:00
										 |  |  |       chan[c.chan].duty=c.value; | 
					
						
							| 
									
										
										
										
											2021-05-28 02:30:18 -04:00
										 |  |  |       if (c.chan!=2) { | 
					
						
							| 
									
										
										
										
											2021-05-28 02:26:57 -04:00
										 |  |  |         chan[c.chan].freqChanged=true; | 
					
						
							| 
									
										
										
										
											2022-04-21 03:24:06 -04:00
										 |  |  |         rWrite(16+c.chan*5+1,((chan[c.chan].duty&3)<<6)|(63-(parent->getIns(chan[c.chan].ins,DIV_INS_GB)->gb.soundLen&63))); | 
					
						
							| 
									
										
										
										
											2021-05-28 02:26:57 -04:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2021-05-28 00:33:04 -04:00
										 |  |  |     case DIV_CMD_PANNING: { | 
					
						
							|  |  |  |       lastPan&=~(0x11<<c.chan); | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:14 -04:00
										 |  |  |       int pan=0; | 
					
						
							|  |  |  |       if (c.value>0) pan|=0x10; | 
					
						
							|  |  |  |       if (c.value2>0) pan|=0x01; | 
					
						
							|  |  |  |       if (pan==0) pan=0x11; | 
					
						
							|  |  |  |       lastPan|=pan<<c.chan; | 
					
						
							| 
									
										
										
										
											2021-12-18 03:25:42 -05:00
										 |  |  |       rWrite(0x25,procMute()); | 
					
						
							| 
									
										
										
										
											2021-05-28 00:33:04 -04:00
										 |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |     case DIV_CMD_LEGATO: | 
					
						
							| 
									
										
										
										
											2021-05-28 00:03:10 -04:00
										 |  |  |       if (c.chan==3) break; | 
					
						
							| 
									
										
										
										
											2022-12-17 02:07:24 -05:00
										 |  |  |       chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0))); | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |       chan[c.chan].freqChanged=true; | 
					
						
							|  |  |  |       chan[c.chan].note=c.value; | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2022-02-07 00:49:01 -05:00
										 |  |  |     case DIV_CMD_PRE_PORTA: | 
					
						
							| 
									
										
										
										
											2022-02-08 22:49:52 -05:00
										 |  |  |       if (chan[c.chan].active && c.value2) { | 
					
						
							| 
									
										
										
										
											2022-04-28 02:31:16 -04:00
										 |  |  |         if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_GB)); | 
					
						
							| 
									
										
										
										
											2022-02-07 00:30:15 -05:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-12-17 02:10:20 -05:00
										 |  |  |       if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will && !NEW_ARP_STRAT) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note); | 
					
						
							| 
									
										
										
										
											2021-05-28 03:30:09 -04:00
										 |  |  |       chan[c.chan].inPorta=c.value; | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2021-05-28 02:26:57 -04:00
										 |  |  |     case DIV_CMD_GB_SWEEP_DIR: | 
					
						
							| 
									
										
										
										
											2022-02-17 22:19:01 -05:00
										 |  |  |       if (c.chan>0) break; | 
					
						
							| 
									
										
										
										
											2021-05-28 02:26:57 -04:00
										 |  |  |       chan[c.chan].sweep&=0xf7; | 
					
						
							|  |  |  |       if (c.value&1) { | 
					
						
							|  |  |  |         chan[c.chan].sweep|=8; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       chan[c.chan].sweepChanged=true; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case DIV_CMD_GB_SWEEP_TIME: | 
					
						
							| 
									
										
										
										
											2022-02-17 22:19:01 -05:00
										 |  |  |       if (c.chan>0) break; | 
					
						
							| 
									
										
										
										
											2021-05-28 02:26:57 -04:00
										 |  |  |       chan[c.chan].sweep&=8; | 
					
						
							|  |  |  |       chan[c.chan].sweep|=c.value&0x77; | 
					
						
							|  |  |  |       chan[c.chan].sweepChanged=true; | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |     case DIV_CMD_GET_VOLMAX: | 
					
						
							|  |  |  |       return 15; | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2022-12-17 00:09:56 -05:00
										 |  |  |     case DIV_CMD_MACRO_OFF: | 
					
						
							|  |  |  |       chan[c.chan].std.mask(c.value,true); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case DIV_CMD_MACRO_ON: | 
					
						
							|  |  |  |       chan[c.chan].std.mask(c.value,false); | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2024-01-17 14:48:47 -05:00
										 |  |  |     case DIV_CMD_MACRO_RESTART: | 
					
						
							|  |  |  |       chan[c.chan].std.restart(c.value); | 
					
						
							| 
									
										
										
										
											2024-01-17 07:28:29 -05:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |     default: | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-21 01:29:07 -05:00
										 |  |  | void DivPlatformGB::forceIns() { | 
					
						
							|  |  |  |   for (int i=0; i<4; i++) { | 
					
						
							|  |  |  |     chan[i].insChanged=true; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-01-24 02:09:03 -05:00
										 |  |  |   immWrite(0x25,procMute()); | 
					
						
							| 
									
										
										
										
											2021-12-21 01:29:07 -05:00
										 |  |  |   updateWave(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-27 00:29:16 -05:00
										 |  |  | void* DivPlatformGB::getChanState(int ch) { | 
					
						
							|  |  |  |   return &chan[ch]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-05 19:17:00 -04:00
										 |  |  | DivMacroInt* DivPlatformGB::getChanMacroInt(int ch) { | 
					
						
							|  |  |  |   return &chan[ch].std; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-23 18:25:05 -04:00
										 |  |  | unsigned short DivPlatformGB::getPan(int ch) { | 
					
						
							|  |  |  |   unsigned char p=lastPan&(0x11<<ch); | 
					
						
							|  |  |  |   return ((p&0xf0)?0x100:0)|((p&0x0f)?1:0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-30 19:33:12 -04:00
										 |  |  | DivDispatchOscBuffer* DivPlatformGB::getOscBuffer(int ch) { | 
					
						
							|  |  |  |   return oscBuf[ch]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 22:31:27 -05:00
										 |  |  | unsigned char* DivPlatformGB::getRegisterPool() { | 
					
						
							|  |  |  |   return regPool; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int DivPlatformGB::getRegisterPoolSize() { | 
					
						
							|  |  |  |   return 64; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-11 13:14:38 -05:00
										 |  |  | void DivPlatformGB::reset() { | 
					
						
							|  |  |  |   for (int i=0; i<4; i++) { | 
					
						
							|  |  |  |     chan[i]=DivPlatformGB::Channel(); | 
					
						
							| 
									
										
										
										
											2022-04-15 06:37:23 -04:00
										 |  |  |     chan[i].std.setEngine(parent); | 
					
						
							| 
									
										
										
										
											2021-12-11 13:14:38 -05:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-04-08 03:11:33 -04:00
										 |  |  |   ws.setEngine(parent); | 
					
						
							|  |  |  |   ws.init(NULL,32,15,false); | 
					
						
							| 
									
										
										
										
											2022-01-25 18:46:27 -05:00
										 |  |  |   if (dumpWrites) { | 
					
						
							|  |  |  |     addWrite(0xffffffff,0); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |   memset(gb,0,sizeof(GB_gameboy_t)); | 
					
						
							| 
									
										
										
										
											2022-02-21 22:31:27 -05:00
										 |  |  |   memset(regPool,0,128); | 
					
						
							| 
									
										
										
										
											2022-08-11 01:46:15 -04:00
										 |  |  |   gb->model=model; | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |   GB_apu_init(gb); | 
					
						
							|  |  |  |   GB_set_sample_rate(gb,rate); | 
					
						
							| 
									
										
										
										
											2021-05-26 18:43:14 -04:00
										 |  |  |   // enable all channels
 | 
					
						
							| 
									
										
										
										
											2022-01-24 02:09:03 -05:00
										 |  |  |   immWrite(0x10,0); | 
					
						
							|  |  |  |   immWrite(0x26,0x8f); | 
					
						
							| 
									
										
										
										
											2021-05-28 00:33:04 -04:00
										 |  |  |   lastPan=0xff; | 
					
						
							| 
									
										
										
										
											2022-01-24 02:09:03 -05:00
										 |  |  |   immWrite(0x25,procMute()); | 
					
						
							|  |  |  |   immWrite(0x24,0x77); | 
					
						
							| 
									
										
										
										
											2022-08-03 20:17:18 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   antiClickPeriodCount=0; | 
					
						
							|  |  |  |   antiClickWavePos=0; | 
					
						
							| 
									
										
										
										
											2024-01-09 23:17:36 -05:00
										 |  |  |   doubleWave=false; | 
					
						
							|  |  |  |   lastDoubleWave=false; | 
					
						
							| 
									
										
										
										
											2021-12-11 13:14:38 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-11 00:56:25 -04:00
										 |  |  | int DivPlatformGB::getPortaFloor(int ch) { | 
					
						
							|  |  |  |   return 24; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-01 19:46:08 -05:00
										 |  |  | int DivPlatformGB::getOutputCount() { | 
					
						
							|  |  |  |   return 2; | 
					
						
							| 
									
										
										
										
											2021-12-11 13:14:38 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-11 01:46:15 -04:00
										 |  |  | bool DivPlatformGB::getDCOffRequired() { | 
					
						
							|  |  |  |   return (model==GB_MODEL_AGB); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-17 23:59:52 -05:00
										 |  |  | void DivPlatformGB::notifyInsChange(int ins) { | 
					
						
							|  |  |  |   for (int i=0; i<4; i++) { | 
					
						
							|  |  |  |     if (chan[i].ins==ins) { | 
					
						
							|  |  |  |       chan[i].insChanged=true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 00:25:10 -05:00
										 |  |  | void DivPlatformGB::notifyWaveChange(int wave) { | 
					
						
							|  |  |  |   if (chan[2].wave==wave) { | 
					
						
							| 
									
										
										
										
											2022-04-08 03:11:33 -04:00
										 |  |  |     ws.changeWave1(wave); | 
					
						
							| 
									
										
										
										
											2022-01-18 00:25:10 -05:00
										 |  |  |     updateWave(); | 
					
						
							| 
									
										
										
										
											2022-08-13 00:09:34 -04:00
										 |  |  |     if (!chan[2].keyOff && chan[2].active) chan[2].keyOn=true; | 
					
						
							| 
									
										
										
										
											2022-01-18 00:25:10 -05:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-13 19:36:02 -05:00
										 |  |  | void DivPlatformGB::notifyInsDeletion(void* ins) { | 
					
						
							|  |  |  |   for (int i=0; i<4; i++) { | 
					
						
							|  |  |  |     chan[i].std.notifyInsDeletion((DivInstrument*)ins); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-01 18:08:19 -05:00
										 |  |  | void DivPlatformGB::poke(unsigned int addr, unsigned short val) { | 
					
						
							|  |  |  |   immWrite(addr,val); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DivPlatformGB::poke(std::vector<DivRegWrite>& wlist) { | 
					
						
							|  |  |  |   for (DivRegWrite& i: wlist) immWrite(i.addr,i.val); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 21:13:40 -04:00
										 |  |  | void DivPlatformGB::setFlags(const DivConfig& flags) { | 
					
						
							|  |  |  |   antiClickEnabled=!flags.getBool("noAntiClick",false); | 
					
						
							| 
									
										
										
										
											2024-01-09 23:17:36 -05:00
										 |  |  |   extendWave=flags.getBool("extendWave",false); | 
					
						
							|  |  |  |   outDepth=flags.getInt("dacDepth",9); | 
					
						
							| 
									
										
										
										
											2022-09-29 21:13:40 -04:00
										 |  |  |   switch (flags.getInt("chipType",0)) { | 
					
						
							| 
									
										
										
										
											2022-08-11 01:46:15 -04:00
										 |  |  |     case 0: | 
					
						
							|  |  |  |       model=GB_MODEL_DMG_B; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case 1: | 
					
						
							|  |  |  |       model=GB_MODEL_CGB_C; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case 2: | 
					
						
							|  |  |  |       model=GB_MODEL_CGB_E; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case 3: | 
					
						
							| 
									
										
										
										
											2024-01-09 23:17:36 -05:00
										 |  |  |       model=extendWave?GB_MODEL_AGB_NATIVE:GB_MODEL_AGB; | 
					
						
							| 
									
										
										
										
											2022-08-11 01:46:15 -04:00
										 |  |  |       break; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-05-04 03:18:56 -04:00
										 |  |  |   invertWave=flags.getBool("invertWave",true); | 
					
						
							| 
									
										
										
										
											2022-10-02 01:06:06 -04:00
										 |  |  |   enoughAlready=flags.getBool("enoughAlready",false); | 
					
						
							| 
									
										
										
										
											2022-08-03 20:17:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-30 19:33:12 -04:00
										 |  |  |   chipClock=4194304; | 
					
						
							| 
									
										
										
										
											2022-12-04 02:04:42 -05:00
										 |  |  |   CHECK_CUSTOM_CLOCK; | 
					
						
							| 
									
										
										
										
											2024-01-09 23:17:36 -05:00
										 |  |  |   rate=chipClock>>(outDepth-2); | 
					
						
							| 
									
										
										
										
											2021-12-18 03:25:42 -05:00
										 |  |  |   for (int i=0; i<4; i++) { | 
					
						
							| 
									
										
										
										
											2022-04-30 19:33:12 -04:00
										 |  |  |     oscBuf[i]->rate=rate; | 
					
						
							| 
									
										
										
										
											2021-12-18 03:25:42 -05:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-07-02 01:39:50 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int DivPlatformGB::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) { | 
					
						
							| 
									
										
										
										
											2021-12-11 13:14:38 -05:00
										 |  |  |   parent=p; | 
					
						
							| 
									
										
										
										
											2022-01-16 23:21:27 -05:00
										 |  |  |   dumpWrites=false; | 
					
						
							| 
									
										
										
										
											2021-12-21 16:02:31 -05:00
										 |  |  |   skipRegisterWrites=false; | 
					
						
							| 
									
										
										
										
											2022-08-11 01:46:15 -04:00
										 |  |  |   model=GB_MODEL_DMG_B; | 
					
						
							| 
									
										
										
										
											2021-12-11 13:14:38 -05:00
										 |  |  |   gb=new GB_gameboy_t; | 
					
						
							| 
									
										
										
										
											2023-07-08 15:40:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   for (int i=0; i<4; i++) { | 
					
						
							|  |  |  |     isMuted[i]=false; | 
					
						
							|  |  |  |     oscBuf[i]=new DivDispatchOscBuffer; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-03 20:17:18 -04:00
										 |  |  |   setFlags(flags); | 
					
						
							| 
									
										
										
										
											2021-12-11 13:14:38 -05:00
										 |  |  |   reset(); | 
					
						
							| 
									
										
										
										
											2021-05-26 04:17:12 -04:00
										 |  |  |   return 4; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-12-15 00:37:27 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | void DivPlatformGB::quit() { | 
					
						
							| 
									
										
										
										
											2022-04-30 19:33:12 -04:00
										 |  |  |   for (int i=0; i<4; i++) { | 
					
						
							|  |  |  |     delete oscBuf[i]; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-12-15 00:37:27 -05:00
										 |  |  |   delete gb; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DivPlatformGB::~DivPlatformGB() { | 
					
						
							| 
									
										
										
										
											2022-01-17 13:29:35 -05:00
										 |  |  | } |