diff --git a/CMakeLists.txt b/CMakeLists.txt index ef82bf7a6..15f279fdf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -274,6 +274,7 @@ src/engine/pattern.cpp src/engine/playback.cpp src/engine/sample.cpp src/engine/song.cpp +src/engine/sysDef.cpp src/engine/wavetable.cpp src/engine/vgmOps.cpp src/engine/platform/abstract.cpp diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 5ddfd4bdb..ce8bcc7c5 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -45,1345 +45,6 @@ void process(void* u, float** in, float** out, int inChans, int outChans, unsign ((DivEngine*)u)->nextBuf(in,out,inChans,outChans,size); } -DivSystem DivEngine::systemFromFile(unsigned char val) { - switch (val) { - case 0x01: - return DIV_SYSTEM_YMU759; - case 0x02: - return DIV_SYSTEM_GENESIS; - case 0x03: - return DIV_SYSTEM_SMS; - case 0x04: - return DIV_SYSTEM_GB; - case 0x05: - return DIV_SYSTEM_PCE; - case 0x06: - return DIV_SYSTEM_NES; - case 0x07: - return DIV_SYSTEM_C64_8580; - case 0x08: - return DIV_SYSTEM_ARCADE; - case 0x09: - return DIV_SYSTEM_YM2610; - case 0x42: - return DIV_SYSTEM_GENESIS_EXT; - case 0x47: - return DIV_SYSTEM_C64_6581; - case 0x49: - return DIV_SYSTEM_YM2610_EXT; - // Furnace-specific systems - case 0x80: - return DIV_SYSTEM_AY8910; - case 0x81: - return DIV_SYSTEM_AMIGA; - case 0x82: - return DIV_SYSTEM_YM2151; - case 0x83: - return DIV_SYSTEM_YM2612; - case 0x84: - return DIV_SYSTEM_TIA; - case 0x85: - return DIV_SYSTEM_VIC20; - case 0x86: - return DIV_SYSTEM_PET; - case 0x87: - return DIV_SYSTEM_SNES; - case 0x88: - return DIV_SYSTEM_VRC6; - case 0x89: - return DIV_SYSTEM_OPLL; - case 0x8a: - return DIV_SYSTEM_FDS; - case 0x8b: - return DIV_SYSTEM_MMC5; - case 0x8c: - return DIV_SYSTEM_N163; - case 0x8d: - return DIV_SYSTEM_OPN; - case 0x8e: - return DIV_SYSTEM_PC98; - case 0x8f: - return DIV_SYSTEM_OPL; - case 0x90: - return DIV_SYSTEM_OPL2; - case 0x91: - return DIV_SYSTEM_OPL3; - case 0x92: - return DIV_SYSTEM_MULTIPCM; - case 0x93: - return DIV_SYSTEM_PCSPKR; - case 0x94: - return DIV_SYSTEM_POKEY; - case 0x95: - return DIV_SYSTEM_RF5C68; - case 0x96: - return DIV_SYSTEM_SWAN; - case 0x97: - return DIV_SYSTEM_SAA1099; - case 0x98: - return DIV_SYSTEM_OPZ; - case 0x99: - return DIV_SYSTEM_POKEMINI; - case 0x9a: - return DIV_SYSTEM_AY8930; - case 0x9b: - return DIV_SYSTEM_SEGAPCM; - case 0x9c: - return DIV_SYSTEM_VBOY; - case 0x9d: - return DIV_SYSTEM_VRC7; - case 0x9e: - return DIV_SYSTEM_YM2610B; - case 0x9f: - return DIV_SYSTEM_SFX_BEEPER; - case 0xa0: - return DIV_SYSTEM_YM2612_EXT; - case 0xa1: - return DIV_SYSTEM_SCC; - case 0xa2: - return DIV_SYSTEM_OPL_DRUMS; - case 0xa3: - return DIV_SYSTEM_OPL2_DRUMS; - case 0xa4: - return DIV_SYSTEM_OPL3_DRUMS; - case 0xa5: - return DIV_SYSTEM_YM2610_FULL; - case 0xa6: - return DIV_SYSTEM_YM2610_FULL_EXT; - case 0xa7: - return DIV_SYSTEM_OPLL_DRUMS; - } - return DIV_SYSTEM_NULL; -} - -unsigned char DivEngine::systemToFile(DivSystem val) { - switch (val) { - case DIV_SYSTEM_YMU759: - return 0x01; - case DIV_SYSTEM_GENESIS: - return 0x02; - case DIV_SYSTEM_SMS: - return 0x03; - case DIV_SYSTEM_GB: - return 0x04; - case DIV_SYSTEM_PCE: - return 0x05; - case DIV_SYSTEM_NES: - return 0x06; - case DIV_SYSTEM_C64_8580: - return 0x07; - case DIV_SYSTEM_ARCADE: - return 0x08; - case DIV_SYSTEM_YM2610: - return 0x09; - case DIV_SYSTEM_GENESIS_EXT: - return 0x42; - case DIV_SYSTEM_C64_6581: - return 0x47; - case DIV_SYSTEM_YM2610_EXT: - return 0x49; - // Furnace-specific systems - case DIV_SYSTEM_AY8910: - return 0x80; - case DIV_SYSTEM_AMIGA: - return 0x81; - case DIV_SYSTEM_YM2151: - return 0x82; - case DIV_SYSTEM_YM2612: - return 0x83; - case DIV_SYSTEM_TIA: - return 0x84; - case DIV_SYSTEM_VIC20: - return 0x85; - case DIV_SYSTEM_PET: - return 0x86; - case DIV_SYSTEM_SNES: - return 0x87; - case DIV_SYSTEM_VRC6: - return 0x88; - case DIV_SYSTEM_OPLL: - return 0x89; - case DIV_SYSTEM_FDS: - return 0x8a; - case DIV_SYSTEM_MMC5: - return 0x8b; - case DIV_SYSTEM_N163: - return 0x8c; - case DIV_SYSTEM_OPN: - return 0x8d; - case DIV_SYSTEM_PC98: - return 0x8e; - case DIV_SYSTEM_OPL: - return 0x8f; - case DIV_SYSTEM_OPL2: - return 0x90; - case DIV_SYSTEM_OPL3: - return 0x91; - case DIV_SYSTEM_MULTIPCM: - return 0x92; - case DIV_SYSTEM_PCSPKR: - return 0x93; - case DIV_SYSTEM_POKEY: - return 0x94; - case DIV_SYSTEM_RF5C68: - return 0x95; - case DIV_SYSTEM_SWAN: - return 0x96; - case DIV_SYSTEM_SAA1099: - return 0x97; - case DIV_SYSTEM_OPZ: - return 0x98; - case DIV_SYSTEM_POKEMINI: - return 0x99; - case DIV_SYSTEM_AY8930: - return 0x9a; - case DIV_SYSTEM_SEGAPCM: - return 0x9b; - case DIV_SYSTEM_VBOY: - return 0x9c; - case DIV_SYSTEM_VRC7: - return 0x9d; - case DIV_SYSTEM_YM2610B: - return 0x9e; - case DIV_SYSTEM_SFX_BEEPER: - return 0x9f; - case DIV_SYSTEM_YM2612_EXT: - return 0xa0; - case DIV_SYSTEM_SCC: - return 0xa1; - case DIV_SYSTEM_OPL_DRUMS: - return 0xa2; - case DIV_SYSTEM_OPL2_DRUMS: - return 0xa3; - case DIV_SYSTEM_OPL3_DRUMS: - return 0xa4; - case DIV_SYSTEM_YM2610_FULL: - return 0xa5; - case DIV_SYSTEM_YM2610_FULL_EXT: - return 0xa6; - case DIV_SYSTEM_OPLL_DRUMS: - return 0xa7; - - case DIV_SYSTEM_NULL: - return 0; - } - return 0; -} - -int DivEngine::getChannelCount(DivSystem sys) { - switch (sys) { - case DIV_SYSTEM_NULL: - return 0; - case DIV_SYSTEM_YMU759: - return 17; - case DIV_SYSTEM_GENESIS: - return 10; - case DIV_SYSTEM_SMS: - case DIV_SYSTEM_GB: - return 4; - case DIV_SYSTEM_PCE: - return 6; - case DIV_SYSTEM_NES: - return 5; - case DIV_SYSTEM_C64_6581: - case DIV_SYSTEM_C64_8580: - return 3; - case DIV_SYSTEM_ARCADE: - case DIV_SYSTEM_GENESIS_EXT: - case DIV_SYSTEM_YM2610: - return 13; - case DIV_SYSTEM_YM2610_EXT: - return 16; - // Furnace-specific systems - case DIV_SYSTEM_AY8910: - case DIV_SYSTEM_AY8930: - return 3; - case DIV_SYSTEM_AMIGA: - return 4; - case DIV_SYSTEM_YM2151: - return 8; - case DIV_SYSTEM_YM2612: - return 6; - case DIV_SYSTEM_TIA: - return 2; - case DIV_SYSTEM_VIC20: - return 4; - case DIV_SYSTEM_PET: - return 1; - case DIV_SYSTEM_SNES: - return 8; - case DIV_SYSTEM_VRC6: - return 3; - case DIV_SYSTEM_OPLL: - return 9; - case DIV_SYSTEM_FDS: - return 1; - case DIV_SYSTEM_MMC5: - return 3; - case DIV_SYSTEM_N163: - return 8; - case DIV_SYSTEM_OPN: - return 6; - case DIV_SYSTEM_PC98: - return 16; - case DIV_SYSTEM_OPL: - return 9; - case DIV_SYSTEM_OPL2: - return 9; - case DIV_SYSTEM_OPL3: - return 18; - case DIV_SYSTEM_MULTIPCM: - return 24; - case DIV_SYSTEM_PCSPKR: - return 1; - case DIV_SYSTEM_POKEY: - return 4; - case DIV_SYSTEM_RF5C68: - return 8; - case DIV_SYSTEM_SWAN: - return 4; - case DIV_SYSTEM_SAA1099: - return 6; - case DIV_SYSTEM_OPZ: - return 8; - case DIV_SYSTEM_POKEMINI: - return 1; - case DIV_SYSTEM_SEGAPCM: - return 16; - case DIV_SYSTEM_VBOY: - return 6; - case DIV_SYSTEM_VRC7: - return 6; - case DIV_SYSTEM_YM2610B: - return 16; - case DIV_SYSTEM_SFX_BEEPER: - return 6; - case DIV_SYSTEM_YM2612_EXT: - return 9; - case DIV_SYSTEM_SCC: - return 5; - case DIV_SYSTEM_OPL_DRUMS: - return 11; - case DIV_SYSTEM_OPL2_DRUMS: - return 11; - case DIV_SYSTEM_OPL3_DRUMS: - return 20; - case DIV_SYSTEM_YM2610_FULL: - return 14; - case DIV_SYSTEM_YM2610_FULL_EXT: - return 17; - case DIV_SYSTEM_OPLL_DRUMS: - return 11; - } - return 0; -} - -int DivEngine::getTotalChannelCount() { - return chans; -} - -// TODO: replace with a better strategy to determine name -const char* DivEngine::getSystemName(DivSystem sys) { - switch (sys) { - case DIV_SYSTEM_NULL: - return "Unknown"; - case DIV_SYSTEM_YMU759: - return "Yamaha YMU759"; - case DIV_SYSTEM_GENESIS: - return "Sega Genesis/Mega Drive"; - case DIV_SYSTEM_SMS: - return "Sega Master System"; - case DIV_SYSTEM_GB: - return "Game Boy"; - case DIV_SYSTEM_PCE: - return "PC Engine/TurboGrafx-16"; - case DIV_SYSTEM_NES: - return "NES"; - case DIV_SYSTEM_C64_6581: - return "Commodore 64 with 6581"; - case DIV_SYSTEM_C64_8580: - return "Commodore 64 with 8580"; - case DIV_SYSTEM_ARCADE: - return "YM2151 + SegaPCM Arcade"; - case DIV_SYSTEM_GENESIS_EXT: - return "Sega Genesis Extended Channel 3"; - case DIV_SYSTEM_YM2610: - return "Neo Geo CD"; - case DIV_SYSTEM_YM2610_EXT: - return "Neo Geo CD Extended Channel 2"; - // Furnace-specific systems - case DIV_SYSTEM_YM2610_FULL: - return "Neo Geo"; - case DIV_SYSTEM_YM2610_FULL_EXT: - return "Neo Geo Extended Channel 2"; - case DIV_SYSTEM_AY8910: - return "AY-3-8910"; - case DIV_SYSTEM_AMIGA: - return "Amiga"; - case DIV_SYSTEM_YM2151: - return "Yamaha YM2151"; - case DIV_SYSTEM_YM2612: - return "Yamaha YM2612"; - case DIV_SYSTEM_TIA: - return "Atari 2600"; - case DIV_SYSTEM_VIC20: - return "Commodore VIC-20"; - case DIV_SYSTEM_PET: - return "Commodore PET"; - case DIV_SYSTEM_SNES: - return "SNES"; - case DIV_SYSTEM_VRC6: - return "Konami VRC6"; - case DIV_SYSTEM_OPLL: - return "Yamaha OPLL"; - case DIV_SYSTEM_FDS: - return "Famicom Disk System"; - case DIV_SYSTEM_MMC5: - return "MMC5"; - case DIV_SYSTEM_N163: - return "Namco 163"; - case DIV_SYSTEM_OPN: - return "NEC PC-9801-26K"; - case DIV_SYSTEM_PC98: - return "PC-9801-86 + Chibi-oto"; - case DIV_SYSTEM_OPL: - return "Yamaha OPL"; - case DIV_SYSTEM_OPL2: - return "Adlib Music Synthesizer Card"; - case DIV_SYSTEM_OPL3: - return "Yamaha OPL3"; - case DIV_SYSTEM_MULTIPCM: - return "MultiPCM"; - case DIV_SYSTEM_PCSPKR: - return "PC Speaker"; - case DIV_SYSTEM_POKEY: - return "Atari 400/800"; - case DIV_SYSTEM_RF5C68: - return "Ricoh RF5C68"; - case DIV_SYSTEM_SWAN: - return "WonderSwan"; - case DIV_SYSTEM_SAA1099: - return "SAM Coupé"; - case DIV_SYSTEM_OPZ: - return "Yamaha TX81Z/YS200"; - case DIV_SYSTEM_POKEMINI: - return "Pokémon Mini"; - case DIV_SYSTEM_AY8930: - return "Microchip AY8930"; - case DIV_SYSTEM_SEGAPCM: - return "SegaPCM"; - case DIV_SYSTEM_VBOY: - return "Virtual Boy"; - case DIV_SYSTEM_VRC7: - return "Konami VRC7"; - case DIV_SYSTEM_YM2610B: - return "Taito Arcade"; - case DIV_SYSTEM_SFX_BEEPER: - return "ZX Spectrum Beeper"; - case DIV_SYSTEM_YM2612_EXT: - return "Yamaha YM2612 Extended Channel 3"; - case DIV_SYSTEM_SCC: - return "Konami SCC"; - case DIV_SYSTEM_OPL_DRUMS: - return "Yamaha OPL with drums"; - case DIV_SYSTEM_OPL2_DRUMS: - return "Yamaha OPL2 with drums"; - case DIV_SYSTEM_OPL3_DRUMS: - return "Yamaha OPL3 with drums"; - case DIV_SYSTEM_OPLL_DRUMS: - return "Yamaha OPLL with drums"; - } - return "Unknown"; -} - -const char* DivEngine::getSystemChips(DivSystem sys) { - switch (sys) { - case DIV_SYSTEM_NULL: - return "Unknown"; - case DIV_SYSTEM_YMU759: - return "Yamaha YMU759"; - case DIV_SYSTEM_GENESIS: - return "Yamaha YM2612 + TI SN76489"; - case DIV_SYSTEM_SMS: - return "TI SN76489"; - case DIV_SYSTEM_GB: - return "Game Boy"; - case DIV_SYSTEM_PCE: - return "Hudson Soft HuC6280"; - case DIV_SYSTEM_NES: - return "Ricoh 2A03"; - case DIV_SYSTEM_C64_6581: - return "SID 6581"; - case DIV_SYSTEM_C64_8580: - return "SID 8580"; - case DIV_SYSTEM_ARCADE: - return "Yamaha YM2151 + SegaPCM"; - case DIV_SYSTEM_GENESIS_EXT: - return "Yamaha YM2612 (extended channel 3) + TI SN76489"; - case DIV_SYSTEM_YM2610: - return "Yamaha YM2610 no ADPCM-B"; - case DIV_SYSTEM_YM2610_EXT: - return "Yamaha YM2610 no ADPCM-B (extended channel 2)"; - // Furnace-specific systems - case DIV_SYSTEM_AY8910: - return "AY-3-8910"; - case DIV_SYSTEM_AMIGA: - return "Paula"; - case DIV_SYSTEM_YM2151: - return "Yamaha YM2151 standalone"; - case DIV_SYSTEM_YM2612: - return "Yamaha YM2612 standalone"; - case DIV_SYSTEM_TIA: - return "Atari TIA"; - case DIV_SYSTEM_VIC20: - return "VIC"; - case DIV_SYSTEM_PET: - return "Commodore PET"; - case DIV_SYSTEM_SNES: - return "SPC700"; - case DIV_SYSTEM_VRC6: - return "Konami VRC6"; - case DIV_SYSTEM_OPLL: - return "Yamaha YM2413"; - case DIV_SYSTEM_FDS: - return "Famicom Disk System"; - case DIV_SYSTEM_MMC5: - return "MMC5"; - case DIV_SYSTEM_N163: - return "Namco 163"; - case DIV_SYSTEM_OPN: - return "Yamaha YM2203"; - case DIV_SYSTEM_PC98: - return "Yamaha YM2608"; - case DIV_SYSTEM_OPL: - return "Yamaha YM3526"; - case DIV_SYSTEM_OPL2: - return "Yamaha YM3812"; - case DIV_SYSTEM_OPL3: - return "Yamaha YMF262"; - case DIV_SYSTEM_MULTIPCM: - return "Yamaha YMW258"; - case DIV_SYSTEM_PCSPKR: - return "Intel 8253"; - case DIV_SYSTEM_POKEY: - return "POKEY"; - case DIV_SYSTEM_RF5C68: - return "Ricoh RF5C68"; - case DIV_SYSTEM_SWAN: - return "WonderSwan"; - case DIV_SYSTEM_SAA1099: - return "Philips SAA1099"; - case DIV_SYSTEM_OPZ: - return "Yamaha YM2414"; - case DIV_SYSTEM_POKEMINI: - return "Pokémon Mini"; - case DIV_SYSTEM_AY8930: - return "Microchip AY8930"; - case DIV_SYSTEM_SEGAPCM: - return "SegaPCM"; - case DIV_SYSTEM_VBOY: - return "VSU"; - case DIV_SYSTEM_VRC7: - return "Konami VRC7"; - case DIV_SYSTEM_YM2610B: - return "Yamaha YM2610B"; - case DIV_SYSTEM_SFX_BEEPER: - return "ZX Spectrum Beeper"; - case DIV_SYSTEM_YM2612_EXT: - return "Yamaha YM2612 Extended Channel 3"; - case DIV_SYSTEM_SCC: - return "Konami K051649"; - case DIV_SYSTEM_OPL_DRUMS: - return "Yamaha YM3526 with drums"; - case DIV_SYSTEM_OPL2_DRUMS: - return "Yamaha YM3812 with drums"; - case DIV_SYSTEM_OPL3_DRUMS: - return "Yamaha YMF262 with drums"; - case DIV_SYSTEM_YM2610_FULL: - return "Yamaha YM2610"; - case DIV_SYSTEM_YM2610_FULL_EXT: - return "Yamaha YM2610 (extended channel 2)"; - case DIV_SYSTEM_OPLL_DRUMS: - return "Yamaha YM2413 with drums"; - } - return "Unknown"; -} - -const char* DivEngine::getSystemNameJ(DivSystem sys) { - switch (sys) { - case DIV_SYSTEM_NULL: - return "不明"; - case DIV_SYSTEM_YMU759: - return ""; - case DIV_SYSTEM_GENESIS: - return "セガメガドライブ"; - case DIV_SYSTEM_SMS: - return "セガマスターシステム"; - case DIV_SYSTEM_GB: - return "ゲームボーイ"; - case DIV_SYSTEM_PCE: - return "PCエンジン"; - case DIV_SYSTEM_NES: - return "ファミリーコンピュータ"; - case DIV_SYSTEM_C64_6581: - return "コモドール64 (6581)"; - case DIV_SYSTEM_C64_8580: - return "コモドール64 (8580)"; - case DIV_SYSTEM_ARCADE: - return "Arcade"; - case DIV_SYSTEM_GENESIS_EXT: - return ""; - case DIV_SYSTEM_YM2610: - return "業務用ネオジオ"; - case DIV_SYSTEM_YM2610_EXT: - return "業務用ネオジオ"; - case DIV_SYSTEM_YM2610_FULL: - return "業務用ネオジオ"; - case DIV_SYSTEM_YM2610_FULL_EXT: - return "業務用ネオジオ"; - // Furnace-specific systems - case DIV_SYSTEM_AY8910: - return ""; - case DIV_SYSTEM_AMIGA: - return ""; - case DIV_SYSTEM_YM2151: - return ""; - case DIV_SYSTEM_YM2612: - return ""; - case DIV_SYSTEM_TIA: - return ""; - case DIV_SYSTEM_SAA1099: - return ""; - case DIV_SYSTEM_AY8930: - return ""; - default: // TODO - return ""; - } - return "不明"; -} - -bool DivEngine::isFMSystem(DivSystem sys) { - return (sys==DIV_SYSTEM_GENESIS || - sys==DIV_SYSTEM_GENESIS_EXT || - sys==DIV_SYSTEM_ARCADE || - sys==DIV_SYSTEM_YM2610 || - sys==DIV_SYSTEM_YM2610_EXT || - sys==DIV_SYSTEM_YM2610_FULL || - sys==DIV_SYSTEM_YM2610_FULL_EXT || - sys==DIV_SYSTEM_YMU759 || - sys==DIV_SYSTEM_YM2151 || - sys==DIV_SYSTEM_YM2612); -} - -bool DivEngine::isSTDSystem(DivSystem sys) { - return (sys!=DIV_SYSTEM_ARCADE && - sys!=DIV_SYSTEM_YMU759 && - sys!=DIV_SYSTEM_YM2612 && - sys!=DIV_SYSTEM_YM2151); -} - -const char* chanNames[36][24]={ - {"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6", "Channel 7", "Channel 8", "Channel 9", "Channel 10", "Channel 11", "Channel 12", "Channel 13", "Channel 14", "Channel 15", "Channel 16", "PCM"}, // YMU759/SegaPCM - {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Square 1", "Square 2", "Square 3", "Noise"}, // Genesis - {"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "FM 4", "FM 5", "FM 6", "Square 1", "Square 2", "Square 3", "Noise"}, // Genesis (extended channel 3) - {"Square 1", "Square 2", "Square 3", "Noise"}, // SMS - {"Pulse 1", "Pulse 2", "Wavetable", "Noise"}, // GB - {"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6"}, // PCE/ZX Beeper - {"Pulse 1", "Pulse 2", "Triangle", "Noise", "PCM"}, // NES - {"Channel 1", "Channel 2", "Channel 3"}, // C64 - {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "FM 7", "FM 8", "PCM 1", "PCM 2", "PCM 3", "PCM 4", "PCM 5"}, // Arcade - {"FM 1", "FM 2", "FM 3", "FM 4", "PSG 1", "PSG 2", "PSG 3", "ADPCM-A 1", "ADPCM-A 2", "ADPCM-A 3", "ADPCM-A 4", "ADPCM-A 5", "ADPCM-A 6", "ADPCM-B"}, // YM2610 - {"FM 1", "FM 2 OP1", "FM 2 OP2", "FM 2 OP3", "FM 2 OP4", "FM 3", "FM 4", "PSG 1", "PSG 2", "PSG 3", "ADPCM-A 1", "ADPCM-A 2", "ADPCM-A 3", "ADPCM-A 4", "ADPCM-A 5", "ADPCM-A 6", "ADPCM-B"}, // YM2610 (extended channel 2) - {"PSG 1", "PSG 2", "PSG 3"}, // AY-3-8910 - {"Channel 1", "Channel 2", "Channel 3", "Channel 4"}, // Amiga/POKEY/Swan - {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "FM 7", "FM 8"}, // YM2151/YM2414 - {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6"}, // YM2612 - {"Channel 1", "Channel 2"}, // TIA - {"PSG 1", "PSG 2", "PSG 3", "PSG 4", "PSG 5", "PSG 6"}, // SAA1099 - {"PSG 1", "PSG 2", "PSG 3"}, // AY8930 - {"Low", "Mid", "High", "Noise"}, // VIC-20 - {"Wave"}, // PET - {"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6", "Channel 7", "Channel 8"}, // SNES/N163/RF5C68 - {"VRC6 1", "VRC6 2", "VRC6 Saw"}, // VRC6 - {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "FM 7", "FM 8", "FM 9"}, // OPLL/OPL/OPL2/VRC7 - {"FDS"}, // FDS - {"Pulse 1", "Pulse 2", "PCM"}, // MMC5 - {"FM 1", "FM 2", "FM 3", "PSG 1", "PSG 2", "PSG 3"}, // OPN - {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Square 1", "Square 2", "Square 3", "Kick", "Snare", "Top", "HiHat", "Tom", "Rim", "ADPCM"}, // PC-98 - {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "FM 7", "FM 8", "FM 9", "FM 10", "FM 11", "FM 12", "FM 13", "FM 14", "FM 15", "FM 16", "FM 17", "FM 18"}, // OPL3 - {"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6", "Channel 7", "Channel 8", "Channel 9", "Channel 10", "Channel 11", "Channel 12", "Channel 13", "Channel 14", "Channel 15", "Channel 16", "Channel 17", "Channel 18", "Channel 19", "Channel 20", "Channel 21", "Channel 22", "Channel 23", "Channel 24"}, // MultiPCM - {"Square"}, // PC Speaker/Pokémon Mini - {"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Noise"}, // Virtual Boy/SCC - {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "PSG 1", "PSG 2", "PSG 3", "ADPCM-A 1", "ADPCM-A 2", "ADPCM-A 3", "ADPCM-A 4", "ADPCM-A 5", "ADPCM-A 6", "ADPCM-B"}, // YM2610B - {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Kick", "Snare", "Tom", "Top", "HiHat"}, // OPLL/OPL/OPL2 drums - {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "FM 7", "FM 8", "FM 9", "FM 10", "FM 11", "FM 12", "FM 13", "FM 14", "FM 15", "Kick", "Snare", "Tom", "Top", "HiHat"}, // OPL3 drums - {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "4OP 1", "4OP 2", "4OP 3", "4OP 4", "4OP 5", "4OP 6"}, // OPL3 4-op - {"FM 1", "FM 2", "FM 3", "4OP 1", "4OP 2", "4OP 3", "4OP 4", "4OP 5", "4OP 6", "Kick", "Snare", "Tom", "Top", "HiHat"}, // OPL3 4-op + drums -}; - -const char* chanShortNames[36][24]={ - {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "PCM"}, // YMU759 - {"F1", "F2", "F3", "F4", "F5", "F6", "S1", "S2", "S3", "NO"}, // Genesis - {"F1", "F2", "O1", "O2", "O3", "O4", "F4", "F5", "F6", "S1", "S2", "S3", "S4"}, // Genesis (extended channel 3) - {"S1", "S2", "S3", "NO"}, // SMS - {"S1", "S2", "WA", "NO"}, // GB - {"CH1", "CH2", "CH3", "CH4", "CH5", "CH6"}, // PCE - {"S1", "S2", "TR", "NO", "PCM"}, // NES - {"CH1", "CH2", "CH3"}, // C64 - {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "P1", "P2", "P3", "P4", "P5"}, // Arcade - {"F1", "F2", "F3", "F4", "S1", "S2", "S3", "P1", "P2", "P3", "P4", "P5", "P6", "B"}, // YM2610 - {"F1", "O1", "O2", "O3", "O4", "F3", "F4", "S1", "S2", "S3", "P1", "P2", "P3", "P4", "P5", "P6", "B"}, // YM2610 (extended channel 2) - {"S1", "S2", "S3"}, // AY-3-8910 - {"CH1", "CH2", "CH3", "CH4"}, // Amiga - {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8"}, // YM2151 - {"F1", "F2", "F3", "F4", "F5", "F6"}, // YM2612 - {"CH1", "CH2"}, // TIA - {"S1", "S2", "S3", "S4", "S5", "S6"}, // SAA1099 - {"S1", "S2", "S3"}, // AY8930 - {"LO", "MID", "HI", "NO"}, // VIC-20 - {"PET"}, // PET - {"CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7", "CH8"}, // SNES/N163/RF5C68 - {"V1", "V2", "VS"}, // VRC6 - {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"}, // OPLL/OPL/OPL2/VRC7 - {"FDS"}, // FDS - {"S1", "S2", "PCM"}, // MMC5 - {"F1", "F2", "F3", "S1", "S2", "S3"}, // OPN - {"F1", "F2", "F3", "F4", "F5", "F6", "S1", "S2", "S3", "BD", "SD", "TP", "HH", "TM", "RM", "P"}, // PC-98 - {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18"}, // OPL3 - {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"}, // MultiPCM - {"SQ"}, // PC Speaker/Pokémon Mini - {"CH1", "CH2", "CH3", "CH4", "CH5", "NO"}, // Virtual Boy/SCC - {"F1", "F2", "F3", "F4", "F5", "F6", "S1", "S2", "S3", "P1", "P2", "P3", "P4", "P5", "P6", "B"}, // YM2610B - {"F1", "F2", "F3", "F4", "F5", "F6", "BD", "SD", "TM", "TP", "HH"}, // OPLL/OPL/OPL2 drums - {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "BD", "SD", "TM", "TP", "HH"}, // OPL3 drums - {"F1", "F2", "F3", "F4", "F5", "F6", "Q1", "Q2", "Q3", "Q4", "Q5", "Q6"}, // OPL3 4-op - {"F1", "F2", "F3", "Q1", "Q2", "Q3", "Q4", "Q5", "Q6", "BD", "SD", "TM", "TP", "HH"}, // OPL3 4-op + drums -}; - -const int chanTypes[36][24]={ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4}, // YMU759 - {0, 0, 0, 0, 0, 0, 1, 1, 1, 2}, // Genesis - {0, 0, 5, 5, 5, 5, 0, 0, 0, 1, 1, 1, 2}, // Genesis (extended channel 3) - {1, 1, 1, 2}, // SMS - {1, 1, 3, 2}, // GB - {3, 3, 3, 3, 3, 3}, // PCE - {1, 1, 3, 2, 4}, // NES - {2, 2, 2}, // C64 - {0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4}, // Arcade - {0, 0, 0, 0, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4}, // YM2610 - {0, 5, 5, 5, 5, 0, 0, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4}, // YM2610 (extended channel 2) - {1, 1, 1}, // AY-3-8910 - {4, 4, 4, 4}, // Amiga - {0, 0, 0, 0, 0, 0, 0, 0}, // YM2151 - {0, 0, 0, 0, 0, 0}, // YM2612 - {3, 3}, // TIA - {1, 1, 1, 1, 1, 1}, // SAA1099 - {1, 1, 1}, // AY8930 - {1, 1, 1, 2}, // VIC-20 - {1}, // PET - {4, 4, 4, 4, 4, 4, 4, 4}, // SNES/N163/RF5C68 - {1, 1, 3}, // VRC6 - {0, 0, 0, 0, 0, 0, 0, 0, 0}, // OPLL/OPL/OPL2/VRC7 - {3}, // FDS - {1, 1, 4}, // MMC5 - {0, 0, 0, 1, 1, 1}, // OPN - {0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 4}, // PC-98 - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // OPL3 - {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, // MultiPCM - {1}, // PC Speaker/Pokémon Mini - {3, 3, 3, 3, 3, 2}, // Virtual Boy/SCC - {0, 0, 0, 0, 0, 0, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4}, // YM2610B - {0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2}, // OPLL/OPL/OPL2 drums - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2}, // OPL3 drums - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // OPL3 4-op - {0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2}, // OPL3 4-op + drums -}; - -const DivInstrumentType chanPrefType[42][24]={ - {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM}, // YMU759 - {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_STD, DIV_INS_STD, DIV_INS_STD, DIV_INS_STD}, // Genesis - {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_STD, DIV_INS_STD, DIV_INS_STD, DIV_INS_STD}, // Genesis (extended channel 3) - {DIV_INS_STD, DIV_INS_STD, DIV_INS_STD, DIV_INS_STD}, // SMS - {DIV_INS_GB, DIV_INS_GB, DIV_INS_GB, DIV_INS_GB}, // GB - {DIV_INS_PCE, DIV_INS_PCE, DIV_INS_PCE, DIV_INS_PCE, DIV_INS_PCE, DIV_INS_PCE}, // PCE - {DIV_INS_STD, DIV_INS_STD, DIV_INS_STD, DIV_INS_STD, DIV_INS_STD}, // NES - {DIV_INS_C64, DIV_INS_C64, DIV_INS_C64}, // C64 - {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, // Arcade - {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, // YM2610 - {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, // YM2610 (extended channel 2) - {DIV_INS_AY, DIV_INS_AY, DIV_INS_AY}, // AY-3-8910 - {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, // Amiga - {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM}, // YM2151 - {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM}, // YM2612 - {DIV_INS_TIA, DIV_INS_TIA}, // TIA - {DIV_INS_SAA1099, DIV_INS_SAA1099, DIV_INS_SAA1099, DIV_INS_SAA1099, DIV_INS_SAA1099, DIV_INS_SAA1099}, // SAA1099 - {DIV_INS_AY8930, DIV_INS_AY8930, DIV_INS_AY8930}, // AY8930 - {DIV_INS_VIC, DIV_INS_VIC, DIV_INS_VIC, DIV_INS_VIC}, // VIC-20 - {DIV_INS_PET}, // PET - {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, // SNES/N163/RF5C68 - {DIV_INS_VRC6, DIV_INS_VRC6, DIV_INS_VRC6}, // VRC6 - {DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL}, // OPLL/VRC7 - {DIV_INS_FDS}, // FDS - {DIV_INS_STD, DIV_INS_STD, DIV_INS_AMIGA}, // MMC5 - {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY}, // OPN - {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, // PC-98 - {DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL}, // OPL/OPL2/OPL3 - {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, // MultiPCM - {DIV_INS_STD}, // PC Speaker/Pokémon Mini - {DIV_INS_VBOY, DIV_INS_VBOY, DIV_INS_VBOY, DIV_INS_VBOY, DIV_INS_VBOY, DIV_INS_VBOY}, // Virtual Boy - {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, // YM2610B - {DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL}, // OPLL drums - {DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL}, // OPL3 drums - {DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ}, // OPL3 4-op - {DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL}, // OPL3 4-op + drums - {DIV_INS_SCC, DIV_INS_SCC, DIV_INS_SCC, DIV_INS_SCC, DIV_INS_SCC}, // SCC - {DIV_INS_N163, DIV_INS_N163, DIV_INS_N163, DIV_INS_N163, DIV_INS_N163, DIV_INS_N163, DIV_INS_N163, DIV_INS_N163}, // N163 - {DIV_INS_POKEY, DIV_INS_POKEY, DIV_INS_POKEY, DIV_INS_POKEY}, // POKEY - {DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER}, // ZX beeper - {DIV_INS_SWAN, DIV_INS_SWAN, DIV_INS_SWAN, DIV_INS_SWAN}, // Swan - {DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ}, // Z -}; - -const char* DivEngine::getChannelName(int chan) { - if (chan<0 || chan>chans) return "??"; - if (!song.chanName[chan].empty()) return song.chanName[chan].c_str(); - switch (sysOfChan[chan]) { - case DIV_SYSTEM_NULL: case DIV_SYSTEM_YMU759: - return chanNames[0][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_GENESIS: - return chanNames[1][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_GENESIS_EXT: - case DIV_SYSTEM_YM2612_EXT: - return chanNames[2][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_SMS: - return chanNames[3][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_GB: - return chanNames[4][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_PCE: - case DIV_SYSTEM_SFX_BEEPER: - return chanNames[5][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_NES: - return chanNames[6][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_C64_6581: case DIV_SYSTEM_C64_8580: - return chanNames[7][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_ARCADE: - case DIV_SYSTEM_OPZ: - return chanNames[8][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2610: - case DIV_SYSTEM_YM2610_FULL: - return chanNames[9][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2610_EXT: - case DIV_SYSTEM_YM2610_FULL_EXT: - return chanNames[10][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_AY8910: - return chanNames[11][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_AMIGA: - case DIV_SYSTEM_POKEY: - case DIV_SYSTEM_SWAN: - return chanNames[12][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2151: - return chanNames[13][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2612: - return chanNames[14][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_TIA: - return chanNames[15][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_VIC20: - return chanNames[18][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_PET: - return chanNames[19][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_SNES: - case DIV_SYSTEM_N163: - case DIV_SYSTEM_RF5C68: - return chanNames[20][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_VRC6: - return chanNames[21][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPLL: - case DIV_SYSTEM_OPL: - case DIV_SYSTEM_OPL2: - case DIV_SYSTEM_VRC7: - return chanNames[22][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_FDS: - return chanNames[23][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_MMC5: - return chanNames[24][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPN: - return chanNames[25][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_PC98: - return chanNames[26][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPL3: - return chanNames[27][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_MULTIPCM: - case DIV_SYSTEM_SEGAPCM: - return chanNames[28][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_PCSPKR: - case DIV_SYSTEM_POKEMINI: - return chanNames[29][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_VBOY: - case DIV_SYSTEM_SCC: - return chanNames[30][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2610B: - return chanNames[31][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPLL_DRUMS: - case DIV_SYSTEM_OPL_DRUMS: - case DIV_SYSTEM_OPL2_DRUMS: - return chanNames[32][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPL3_DRUMS: - return chanNames[33][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_SAA1099: - return chanNames[16][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_AY8930: - return chanNames[17][dispatchChanOfChan[chan]]; - break; - } - return "??"; -} - -const char* DivEngine::getChannelShortName(int chan) { - if (chan<0 || chan>chans) return "??"; - if (!song.chanShortName[chan].empty()) return song.chanShortName[chan].c_str(); - switch (sysOfChan[chan]) { - case DIV_SYSTEM_NULL: case DIV_SYSTEM_YMU759: - return chanShortNames[0][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_GENESIS: - return chanShortNames[1][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_GENESIS_EXT: - case DIV_SYSTEM_YM2612_EXT: - return chanShortNames[2][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_SMS: - return chanShortNames[3][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_GB: - return chanShortNames[4][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_PCE: - case DIV_SYSTEM_SFX_BEEPER: - return chanShortNames[5][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_NES: - return chanShortNames[6][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_C64_6581: case DIV_SYSTEM_C64_8580: - return chanShortNames[7][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_ARCADE: - case DIV_SYSTEM_OPZ: - return chanShortNames[8][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2610: - case DIV_SYSTEM_YM2610_FULL: - return chanShortNames[9][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2610_EXT: - case DIV_SYSTEM_YM2610_FULL_EXT: - return chanShortNames[10][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_AY8910: - return chanShortNames[11][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_AMIGA: - case DIV_SYSTEM_POKEY: - case DIV_SYSTEM_SWAN: - return chanShortNames[12][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2151: - return chanShortNames[13][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2612: - return chanShortNames[14][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_TIA: - return chanShortNames[15][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_VIC20: - return chanShortNames[18][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_PET: - return chanShortNames[19][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_SNES: - case DIV_SYSTEM_N163: - case DIV_SYSTEM_RF5C68: - return chanShortNames[20][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_VRC6: - return chanShortNames[21][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPLL: - case DIV_SYSTEM_OPL: - case DIV_SYSTEM_OPL2: - case DIV_SYSTEM_VRC7: - return chanShortNames[22][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_FDS: - return chanShortNames[23][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_MMC5: - return chanShortNames[24][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPN: - return chanShortNames[25][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_PC98: - return chanShortNames[26][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPL3: - return chanShortNames[27][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_MULTIPCM: - case DIV_SYSTEM_SEGAPCM: - return chanShortNames[28][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_PCSPKR: - case DIV_SYSTEM_POKEMINI: - return chanShortNames[29][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_VBOY: - case DIV_SYSTEM_SCC: - return chanShortNames[30][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2610B: - return chanShortNames[31][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPLL_DRUMS: - case DIV_SYSTEM_OPL_DRUMS: - case DIV_SYSTEM_OPL2_DRUMS: - return chanShortNames[32][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPL3_DRUMS: - return chanShortNames[33][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_SAA1099: - return chanShortNames[16][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_AY8930: - return chanShortNames[17][dispatchChanOfChan[chan]]; - break; - } - return "??"; -} - -int DivEngine::getChannelType(int chan) { - switch (sysOfChan[chan]) { - case DIV_SYSTEM_NULL: case DIV_SYSTEM_YMU759: - return chanTypes[0][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_GENESIS: - return chanTypes[1][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_GENESIS_EXT: - case DIV_SYSTEM_YM2612_EXT: - return chanTypes[2][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_SMS: - return chanTypes[3][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_GB: - return chanTypes[4][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_PCE: - case DIV_SYSTEM_SFX_BEEPER: - return chanTypes[5][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_NES: - return chanTypes[6][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_C64_6581: case DIV_SYSTEM_C64_8580: - return chanTypes[7][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_ARCADE: - case DIV_SYSTEM_OPZ: - return chanTypes[8][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2610: - case DIV_SYSTEM_YM2610_FULL: - return chanTypes[9][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2610_EXT: - case DIV_SYSTEM_YM2610_FULL_EXT: - return chanTypes[10][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_AY8910: - return chanTypes[11][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_AMIGA: - case DIV_SYSTEM_POKEY: - case DIV_SYSTEM_SWAN: - return chanTypes[12][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2151: - return chanTypes[13][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2612: - return chanTypes[14][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_TIA: - return chanTypes[15][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_VIC20: - return chanTypes[18][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_PET: - return chanTypes[19][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_SNES: - case DIV_SYSTEM_N163: - case DIV_SYSTEM_RF5C68: - return chanTypes[20][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_VRC6: - return chanTypes[21][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPLL: - case DIV_SYSTEM_OPL: - case DIV_SYSTEM_OPL2: - case DIV_SYSTEM_VRC7: - return chanTypes[22][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_FDS: - return chanTypes[23][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_MMC5: - return chanTypes[24][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPN: - return chanTypes[25][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_PC98: - return chanTypes[26][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPL3: - return chanTypes[27][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_MULTIPCM: - case DIV_SYSTEM_SEGAPCM: - return chanTypes[28][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_PCSPKR: - case DIV_SYSTEM_POKEMINI: - return chanTypes[29][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_VBOY: - case DIV_SYSTEM_SCC: - return chanTypes[30][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2610B: - return chanTypes[31][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPLL_DRUMS: - case DIV_SYSTEM_OPL_DRUMS: - case DIV_SYSTEM_OPL2_DRUMS: - return chanTypes[32][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPL3_DRUMS: - return chanTypes[33][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_SAA1099: - return chanTypes[16][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_AY8930: - return chanTypes[17][dispatchChanOfChan[chan]]; - break; - } - return 1; -} - -DivInstrumentType DivEngine::getPreferInsType(int chan) { - switch (sysOfChan[chan]) { - case DIV_SYSTEM_NULL: case DIV_SYSTEM_YMU759: - return chanPrefType[0][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_GENESIS: - return chanPrefType[1][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_GENESIS_EXT: - case DIV_SYSTEM_YM2612_EXT: - return chanPrefType[2][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_SMS: - return chanPrefType[3][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_GB: - return chanPrefType[4][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_PCE: - return chanPrefType[5][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_NES: - return chanPrefType[6][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_C64_6581: case DIV_SYSTEM_C64_8580: - return chanPrefType[7][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_ARCADE: - return chanPrefType[8][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2610: - case DIV_SYSTEM_YM2610_FULL: - return chanPrefType[9][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2610_EXT: - case DIV_SYSTEM_YM2610_FULL_EXT: - return chanPrefType[10][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_AY8910: - return chanPrefType[11][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_AMIGA: - return chanPrefType[12][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2151: - return chanPrefType[13][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2612: - return chanPrefType[14][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_TIA: - return chanPrefType[15][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_VIC20: - return chanPrefType[18][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_PET: - return chanPrefType[19][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_SNES: - case DIV_SYSTEM_RF5C68: - return chanPrefType[20][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_VRC6: - return chanPrefType[21][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPLL: - case DIV_SYSTEM_VRC7: - return chanPrefType[22][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_FDS: - return chanPrefType[23][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_MMC5: - return chanPrefType[24][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPN: - return chanPrefType[25][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_PC98: - return chanPrefType[26][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPL: - case DIV_SYSTEM_OPL2: - case DIV_SYSTEM_OPL3: - return chanPrefType[27][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_MULTIPCM: - case DIV_SYSTEM_SEGAPCM: - return chanPrefType[28][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_PCSPKR: - case DIV_SYSTEM_POKEMINI: - return chanPrefType[29][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_VBOY: - return chanPrefType[30][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_SCC: - return chanPrefType[36][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_N163: - return chanPrefType[37][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_YM2610B: - return chanPrefType[31][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPLL_DRUMS: - return chanPrefType[32][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPL_DRUMS: - case DIV_SYSTEM_OPL2_DRUMS: - case DIV_SYSTEM_OPL3_DRUMS: - return chanPrefType[33][dispatchChanOfChan[chan]]; - return chanPrefType[33][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_SAA1099: - return chanPrefType[16][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_AY8930: - return chanPrefType[17][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_POKEY: - return chanPrefType[38][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_SFX_BEEPER: - return chanPrefType[39][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_SWAN: - return chanPrefType[40][dispatchChanOfChan[chan]]; - break; - case DIV_SYSTEM_OPZ: - return chanPrefType[41][dispatchChanOfChan[chan]]; - break; - } - return DIV_INS_FM; -} - -bool DivEngine::isVGMExportable(DivSystem which) { - switch (which) { - case DIV_SYSTEM_GENESIS: - case DIV_SYSTEM_GENESIS_EXT: - case DIV_SYSTEM_SMS: - case DIV_SYSTEM_GB: - case DIV_SYSTEM_PCE: - case DIV_SYSTEM_NES: - case DIV_SYSTEM_ARCADE: - case DIV_SYSTEM_YM2151: - case DIV_SYSTEM_YM2612: - case DIV_SYSTEM_YM2610: - case DIV_SYSTEM_YM2610_EXT: - case DIV_SYSTEM_AY8910: - case DIV_SYSTEM_AY8930: - case DIV_SYSTEM_SAA1099: - return true; - default: - return false; - } - return false; -} - const char* DivEngine::getEffectDesc(unsigned char effect, int chan) { switch (effect) { case 0x00: diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp new file mode 100644 index 000000000..68deda34e --- /dev/null +++ b/src/engine/sysDef.cpp @@ -0,0 +1,1359 @@ +/** + * 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. + */ + +#include "engine.h" + +DivSystem DivEngine::systemFromFile(unsigned char val) { + switch (val) { + case 0x01: + return DIV_SYSTEM_YMU759; + case 0x02: + return DIV_SYSTEM_GENESIS; + case 0x03: + return DIV_SYSTEM_SMS; + case 0x04: + return DIV_SYSTEM_GB; + case 0x05: + return DIV_SYSTEM_PCE; + case 0x06: + return DIV_SYSTEM_NES; + case 0x07: + return DIV_SYSTEM_C64_8580; + case 0x08: + return DIV_SYSTEM_ARCADE; + case 0x09: + return DIV_SYSTEM_YM2610; + case 0x42: + return DIV_SYSTEM_GENESIS_EXT; + case 0x47: + return DIV_SYSTEM_C64_6581; + case 0x49: + return DIV_SYSTEM_YM2610_EXT; + // Furnace-specific systems + case 0x80: + return DIV_SYSTEM_AY8910; + case 0x81: + return DIV_SYSTEM_AMIGA; + case 0x82: + return DIV_SYSTEM_YM2151; + case 0x83: + return DIV_SYSTEM_YM2612; + case 0x84: + return DIV_SYSTEM_TIA; + case 0x85: + return DIV_SYSTEM_VIC20; + case 0x86: + return DIV_SYSTEM_PET; + case 0x87: + return DIV_SYSTEM_SNES; + case 0x88: + return DIV_SYSTEM_VRC6; + case 0x89: + return DIV_SYSTEM_OPLL; + case 0x8a: + return DIV_SYSTEM_FDS; + case 0x8b: + return DIV_SYSTEM_MMC5; + case 0x8c: + return DIV_SYSTEM_N163; + case 0x8d: + return DIV_SYSTEM_OPN; + case 0x8e: + return DIV_SYSTEM_PC98; + case 0x8f: + return DIV_SYSTEM_OPL; + case 0x90: + return DIV_SYSTEM_OPL2; + case 0x91: + return DIV_SYSTEM_OPL3; + case 0x92: + return DIV_SYSTEM_MULTIPCM; + case 0x93: + return DIV_SYSTEM_PCSPKR; + case 0x94: + return DIV_SYSTEM_POKEY; + case 0x95: + return DIV_SYSTEM_RF5C68; + case 0x96: + return DIV_SYSTEM_SWAN; + case 0x97: + return DIV_SYSTEM_SAA1099; + case 0x98: + return DIV_SYSTEM_OPZ; + case 0x99: + return DIV_SYSTEM_POKEMINI; + case 0x9a: + return DIV_SYSTEM_AY8930; + case 0x9b: + return DIV_SYSTEM_SEGAPCM; + case 0x9c: + return DIV_SYSTEM_VBOY; + case 0x9d: + return DIV_SYSTEM_VRC7; + case 0x9e: + return DIV_SYSTEM_YM2610B; + case 0x9f: + return DIV_SYSTEM_SFX_BEEPER; + case 0xa0: + return DIV_SYSTEM_YM2612_EXT; + case 0xa1: + return DIV_SYSTEM_SCC; + case 0xa2: + return DIV_SYSTEM_OPL_DRUMS; + case 0xa3: + return DIV_SYSTEM_OPL2_DRUMS; + case 0xa4: + return DIV_SYSTEM_OPL3_DRUMS; + case 0xa5: + return DIV_SYSTEM_YM2610_FULL; + case 0xa6: + return DIV_SYSTEM_YM2610_FULL_EXT; + case 0xa7: + return DIV_SYSTEM_OPLL_DRUMS; + } + return DIV_SYSTEM_NULL; +} + +unsigned char DivEngine::systemToFile(DivSystem val) { + switch (val) { + case DIV_SYSTEM_YMU759: + return 0x01; + case DIV_SYSTEM_GENESIS: + return 0x02; + case DIV_SYSTEM_SMS: + return 0x03; + case DIV_SYSTEM_GB: + return 0x04; + case DIV_SYSTEM_PCE: + return 0x05; + case DIV_SYSTEM_NES: + return 0x06; + case DIV_SYSTEM_C64_8580: + return 0x07; + case DIV_SYSTEM_ARCADE: + return 0x08; + case DIV_SYSTEM_YM2610: + return 0x09; + case DIV_SYSTEM_GENESIS_EXT: + return 0x42; + case DIV_SYSTEM_C64_6581: + return 0x47; + case DIV_SYSTEM_YM2610_EXT: + return 0x49; + // Furnace-specific systems + case DIV_SYSTEM_AY8910: + return 0x80; + case DIV_SYSTEM_AMIGA: + return 0x81; + case DIV_SYSTEM_YM2151: + return 0x82; + case DIV_SYSTEM_YM2612: + return 0x83; + case DIV_SYSTEM_TIA: + return 0x84; + case DIV_SYSTEM_VIC20: + return 0x85; + case DIV_SYSTEM_PET: + return 0x86; + case DIV_SYSTEM_SNES: + return 0x87; + case DIV_SYSTEM_VRC6: + return 0x88; + case DIV_SYSTEM_OPLL: + return 0x89; + case DIV_SYSTEM_FDS: + return 0x8a; + case DIV_SYSTEM_MMC5: + return 0x8b; + case DIV_SYSTEM_N163: + return 0x8c; + case DIV_SYSTEM_OPN: + return 0x8d; + case DIV_SYSTEM_PC98: + return 0x8e; + case DIV_SYSTEM_OPL: + return 0x8f; + case DIV_SYSTEM_OPL2: + return 0x90; + case DIV_SYSTEM_OPL3: + return 0x91; + case DIV_SYSTEM_MULTIPCM: + return 0x92; + case DIV_SYSTEM_PCSPKR: + return 0x93; + case DIV_SYSTEM_POKEY: + return 0x94; + case DIV_SYSTEM_RF5C68: + return 0x95; + case DIV_SYSTEM_SWAN: + return 0x96; + case DIV_SYSTEM_SAA1099: + return 0x97; + case DIV_SYSTEM_OPZ: + return 0x98; + case DIV_SYSTEM_POKEMINI: + return 0x99; + case DIV_SYSTEM_AY8930: + return 0x9a; + case DIV_SYSTEM_SEGAPCM: + return 0x9b; + case DIV_SYSTEM_VBOY: + return 0x9c; + case DIV_SYSTEM_VRC7: + return 0x9d; + case DIV_SYSTEM_YM2610B: + return 0x9e; + case DIV_SYSTEM_SFX_BEEPER: + return 0x9f; + case DIV_SYSTEM_YM2612_EXT: + return 0xa0; + case DIV_SYSTEM_SCC: + return 0xa1; + case DIV_SYSTEM_OPL_DRUMS: + return 0xa2; + case DIV_SYSTEM_OPL2_DRUMS: + return 0xa3; + case DIV_SYSTEM_OPL3_DRUMS: + return 0xa4; + case DIV_SYSTEM_YM2610_FULL: + return 0xa5; + case DIV_SYSTEM_YM2610_FULL_EXT: + return 0xa6; + case DIV_SYSTEM_OPLL_DRUMS: + return 0xa7; + + case DIV_SYSTEM_NULL: + return 0; + } + return 0; +} + +int DivEngine::getChannelCount(DivSystem sys) { + switch (sys) { + case DIV_SYSTEM_NULL: + return 0; + case DIV_SYSTEM_YMU759: + return 17; + case DIV_SYSTEM_GENESIS: + return 10; + case DIV_SYSTEM_SMS: + case DIV_SYSTEM_GB: + return 4; + case DIV_SYSTEM_PCE: + return 6; + case DIV_SYSTEM_NES: + return 5; + case DIV_SYSTEM_C64_6581: + case DIV_SYSTEM_C64_8580: + return 3; + case DIV_SYSTEM_ARCADE: + case DIV_SYSTEM_GENESIS_EXT: + case DIV_SYSTEM_YM2610: + return 13; + case DIV_SYSTEM_YM2610_EXT: + return 16; + // Furnace-specific systems + case DIV_SYSTEM_AY8910: + case DIV_SYSTEM_AY8930: + return 3; + case DIV_SYSTEM_AMIGA: + return 4; + case DIV_SYSTEM_YM2151: + return 8; + case DIV_SYSTEM_YM2612: + return 6; + case DIV_SYSTEM_TIA: + return 2; + case DIV_SYSTEM_VIC20: + return 4; + case DIV_SYSTEM_PET: + return 1; + case DIV_SYSTEM_SNES: + return 8; + case DIV_SYSTEM_VRC6: + return 3; + case DIV_SYSTEM_OPLL: + return 9; + case DIV_SYSTEM_FDS: + return 1; + case DIV_SYSTEM_MMC5: + return 3; + case DIV_SYSTEM_N163: + return 8; + case DIV_SYSTEM_OPN: + return 6; + case DIV_SYSTEM_PC98: + return 16; + case DIV_SYSTEM_OPL: + return 9; + case DIV_SYSTEM_OPL2: + return 9; + case DIV_SYSTEM_OPL3: + return 18; + case DIV_SYSTEM_MULTIPCM: + return 24; + case DIV_SYSTEM_PCSPKR: + return 1; + case DIV_SYSTEM_POKEY: + return 4; + case DIV_SYSTEM_RF5C68: + return 8; + case DIV_SYSTEM_SWAN: + return 4; + case DIV_SYSTEM_SAA1099: + return 6; + case DIV_SYSTEM_OPZ: + return 8; + case DIV_SYSTEM_POKEMINI: + return 1; + case DIV_SYSTEM_SEGAPCM: + return 16; + case DIV_SYSTEM_VBOY: + return 6; + case DIV_SYSTEM_VRC7: + return 6; + case DIV_SYSTEM_YM2610B: + return 16; + case DIV_SYSTEM_SFX_BEEPER: + return 6; + case DIV_SYSTEM_YM2612_EXT: + return 9; + case DIV_SYSTEM_SCC: + return 5; + case DIV_SYSTEM_OPL_DRUMS: + return 11; + case DIV_SYSTEM_OPL2_DRUMS: + return 11; + case DIV_SYSTEM_OPL3_DRUMS: + return 20; + case DIV_SYSTEM_YM2610_FULL: + return 14; + case DIV_SYSTEM_YM2610_FULL_EXT: + return 17; + case DIV_SYSTEM_OPLL_DRUMS: + return 11; + } + return 0; +} + +int DivEngine::getTotalChannelCount() { + return chans; +} + +// TODO: replace with a better strategy to determine name +const char* DivEngine::getSystemName(DivSystem sys) { + switch (sys) { + case DIV_SYSTEM_NULL: + return "Unknown"; + case DIV_SYSTEM_YMU759: + return "Yamaha YMU759"; + case DIV_SYSTEM_GENESIS: + return "Sega Genesis/Mega Drive"; + case DIV_SYSTEM_SMS: + return "Sega Master System"; + case DIV_SYSTEM_GB: + return "Game Boy"; + case DIV_SYSTEM_PCE: + return "PC Engine/TurboGrafx-16"; + case DIV_SYSTEM_NES: + return "NES"; + case DIV_SYSTEM_C64_6581: + return "Commodore 64 with 6581"; + case DIV_SYSTEM_C64_8580: + return "Commodore 64 with 8580"; + case DIV_SYSTEM_ARCADE: + return "YM2151 + SegaPCM Arcade"; + case DIV_SYSTEM_GENESIS_EXT: + return "Sega Genesis Extended Channel 3"; + case DIV_SYSTEM_YM2610: + return "Neo Geo CD"; + case DIV_SYSTEM_YM2610_EXT: + return "Neo Geo CD Extended Channel 2"; + // Furnace-specific systems + case DIV_SYSTEM_YM2610_FULL: + return "Neo Geo"; + case DIV_SYSTEM_YM2610_FULL_EXT: + return "Neo Geo Extended Channel 2"; + case DIV_SYSTEM_AY8910: + return "AY-3-8910"; + case DIV_SYSTEM_AMIGA: + return "Amiga"; + case DIV_SYSTEM_YM2151: + return "Yamaha YM2151"; + case DIV_SYSTEM_YM2612: + return "Yamaha YM2612"; + case DIV_SYSTEM_TIA: + return "Atari 2600"; + case DIV_SYSTEM_VIC20: + return "Commodore VIC-20"; + case DIV_SYSTEM_PET: + return "Commodore PET"; + case DIV_SYSTEM_SNES: + return "SNES"; + case DIV_SYSTEM_VRC6: + return "Konami VRC6"; + case DIV_SYSTEM_OPLL: + return "Yamaha OPLL"; + case DIV_SYSTEM_FDS: + return "Famicom Disk System"; + case DIV_SYSTEM_MMC5: + return "MMC5"; + case DIV_SYSTEM_N163: + return "Namco 163"; + case DIV_SYSTEM_OPN: + return "NEC PC-9801-26K"; + case DIV_SYSTEM_PC98: + return "PC-9801-86 + Chibi-oto"; + case DIV_SYSTEM_OPL: + return "Yamaha OPL"; + case DIV_SYSTEM_OPL2: + return "Adlib Music Synthesizer Card"; + case DIV_SYSTEM_OPL3: + return "Yamaha OPL3"; + case DIV_SYSTEM_MULTIPCM: + return "MultiPCM"; + case DIV_SYSTEM_PCSPKR: + return "PC Speaker"; + case DIV_SYSTEM_POKEY: + return "Atari 400/800"; + case DIV_SYSTEM_RF5C68: + return "Ricoh RF5C68"; + case DIV_SYSTEM_SWAN: + return "WonderSwan"; + case DIV_SYSTEM_SAA1099: + return "SAM Coupé"; + case DIV_SYSTEM_OPZ: + return "Yamaha TX81Z/YS200"; + case DIV_SYSTEM_POKEMINI: + return "Pokémon Mini"; + case DIV_SYSTEM_AY8930: + return "Microchip AY8930"; + case DIV_SYSTEM_SEGAPCM: + return "SegaPCM"; + case DIV_SYSTEM_VBOY: + return "Virtual Boy"; + case DIV_SYSTEM_VRC7: + return "Konami VRC7"; + case DIV_SYSTEM_YM2610B: + return "Taito Arcade"; + case DIV_SYSTEM_SFX_BEEPER: + return "ZX Spectrum Beeper"; + case DIV_SYSTEM_YM2612_EXT: + return "Yamaha YM2612 Extended Channel 3"; + case DIV_SYSTEM_SCC: + return "Konami SCC"; + case DIV_SYSTEM_OPL_DRUMS: + return "Yamaha OPL with drums"; + case DIV_SYSTEM_OPL2_DRUMS: + return "Yamaha OPL2 with drums"; + case DIV_SYSTEM_OPL3_DRUMS: + return "Yamaha OPL3 with drums"; + case DIV_SYSTEM_OPLL_DRUMS: + return "Yamaha OPLL with drums"; + } + return "Unknown"; +} + +const char* DivEngine::getSystemChips(DivSystem sys) { + switch (sys) { + case DIV_SYSTEM_NULL: + return "Unknown"; + case DIV_SYSTEM_YMU759: + return "Yamaha YMU759"; + case DIV_SYSTEM_GENESIS: + return "Yamaha YM2612 + TI SN76489"; + case DIV_SYSTEM_SMS: + return "TI SN76489"; + case DIV_SYSTEM_GB: + return "Game Boy"; + case DIV_SYSTEM_PCE: + return "Hudson Soft HuC6280"; + case DIV_SYSTEM_NES: + return "Ricoh 2A03"; + case DIV_SYSTEM_C64_6581: + return "SID 6581"; + case DIV_SYSTEM_C64_8580: + return "SID 8580"; + case DIV_SYSTEM_ARCADE: + return "Yamaha YM2151 + SegaPCM"; + case DIV_SYSTEM_GENESIS_EXT: + return "Yamaha YM2612 (extended channel 3) + TI SN76489"; + case DIV_SYSTEM_YM2610: + return "Yamaha YM2610 no ADPCM-B"; + case DIV_SYSTEM_YM2610_EXT: + return "Yamaha YM2610 no ADPCM-B (extended channel 2)"; + // Furnace-specific systems + case DIV_SYSTEM_AY8910: + return "AY-3-8910"; + case DIV_SYSTEM_AMIGA: + return "Paula"; + case DIV_SYSTEM_YM2151: + return "Yamaha YM2151 standalone"; + case DIV_SYSTEM_YM2612: + return "Yamaha YM2612 standalone"; + case DIV_SYSTEM_TIA: + return "Atari TIA"; + case DIV_SYSTEM_VIC20: + return "VIC"; + case DIV_SYSTEM_PET: + return "Commodore PET"; + case DIV_SYSTEM_SNES: + return "SPC700"; + case DIV_SYSTEM_VRC6: + return "Konami VRC6"; + case DIV_SYSTEM_OPLL: + return "Yamaha YM2413"; + case DIV_SYSTEM_FDS: + return "Famicom Disk System"; + case DIV_SYSTEM_MMC5: + return "MMC5"; + case DIV_SYSTEM_N163: + return "Namco 163"; + case DIV_SYSTEM_OPN: + return "Yamaha YM2203"; + case DIV_SYSTEM_PC98: + return "Yamaha YM2608"; + case DIV_SYSTEM_OPL: + return "Yamaha YM3526"; + case DIV_SYSTEM_OPL2: + return "Yamaha YM3812"; + case DIV_SYSTEM_OPL3: + return "Yamaha YMF262"; + case DIV_SYSTEM_MULTIPCM: + return "Yamaha YMW258"; + case DIV_SYSTEM_PCSPKR: + return "Intel 8253"; + case DIV_SYSTEM_POKEY: + return "POKEY"; + case DIV_SYSTEM_RF5C68: + return "Ricoh RF5C68"; + case DIV_SYSTEM_SWAN: + return "WonderSwan"; + case DIV_SYSTEM_SAA1099: + return "Philips SAA1099"; + case DIV_SYSTEM_OPZ: + return "Yamaha YM2414"; + case DIV_SYSTEM_POKEMINI: + return "Pokémon Mini"; + case DIV_SYSTEM_AY8930: + return "Microchip AY8930"; + case DIV_SYSTEM_SEGAPCM: + return "SegaPCM"; + case DIV_SYSTEM_VBOY: + return "VSU"; + case DIV_SYSTEM_VRC7: + return "Konami VRC7"; + case DIV_SYSTEM_YM2610B: + return "Yamaha YM2610B"; + case DIV_SYSTEM_SFX_BEEPER: + return "ZX Spectrum Beeper"; + case DIV_SYSTEM_YM2612_EXT: + return "Yamaha YM2612 Extended Channel 3"; + case DIV_SYSTEM_SCC: + return "Konami K051649"; + case DIV_SYSTEM_OPL_DRUMS: + return "Yamaha YM3526 with drums"; + case DIV_SYSTEM_OPL2_DRUMS: + return "Yamaha YM3812 with drums"; + case DIV_SYSTEM_OPL3_DRUMS: + return "Yamaha YMF262 with drums"; + case DIV_SYSTEM_YM2610_FULL: + return "Yamaha YM2610"; + case DIV_SYSTEM_YM2610_FULL_EXT: + return "Yamaha YM2610 (extended channel 2)"; + case DIV_SYSTEM_OPLL_DRUMS: + return "Yamaha YM2413 with drums"; + } + return "Unknown"; +} + +const char* DivEngine::getSystemNameJ(DivSystem sys) { + switch (sys) { + case DIV_SYSTEM_NULL: + return "不明"; + case DIV_SYSTEM_YMU759: + return ""; + case DIV_SYSTEM_GENESIS: + return "セガメガドライブ"; + case DIV_SYSTEM_SMS: + return "セガマスターシステム"; + case DIV_SYSTEM_GB: + return "ゲームボーイ"; + case DIV_SYSTEM_PCE: + return "PCエンジン"; + case DIV_SYSTEM_NES: + return "ファミリーコンピュータ"; + case DIV_SYSTEM_C64_6581: + return "コモドール64 (6581)"; + case DIV_SYSTEM_C64_8580: + return "コモドール64 (8580)"; + case DIV_SYSTEM_ARCADE: + return "Arcade"; + case DIV_SYSTEM_GENESIS_EXT: + return ""; + case DIV_SYSTEM_YM2610: + return "業務用ネオジオ"; + case DIV_SYSTEM_YM2610_EXT: + return "業務用ネオジオ"; + case DIV_SYSTEM_YM2610_FULL: + return "業務用ネオジオ"; + case DIV_SYSTEM_YM2610_FULL_EXT: + return "業務用ネオジオ"; + // Furnace-specific systems + case DIV_SYSTEM_AY8910: + return ""; + case DIV_SYSTEM_AMIGA: + return ""; + case DIV_SYSTEM_YM2151: + return ""; + case DIV_SYSTEM_YM2612: + return ""; + case DIV_SYSTEM_TIA: + return ""; + case DIV_SYSTEM_SAA1099: + return ""; + case DIV_SYSTEM_AY8930: + return ""; + default: // TODO + return ""; + } + return "不明"; +} + +bool DivEngine::isFMSystem(DivSystem sys) { + return (sys==DIV_SYSTEM_GENESIS || + sys==DIV_SYSTEM_GENESIS_EXT || + sys==DIV_SYSTEM_ARCADE || + sys==DIV_SYSTEM_YM2610 || + sys==DIV_SYSTEM_YM2610_EXT || + sys==DIV_SYSTEM_YM2610_FULL || + sys==DIV_SYSTEM_YM2610_FULL_EXT || + sys==DIV_SYSTEM_YMU759 || + sys==DIV_SYSTEM_YM2151 || + sys==DIV_SYSTEM_YM2612); +} + +bool DivEngine::isSTDSystem(DivSystem sys) { + return (sys!=DIV_SYSTEM_ARCADE && + sys!=DIV_SYSTEM_YMU759 && + sys!=DIV_SYSTEM_YM2612 && + sys!=DIV_SYSTEM_YM2151); +} + +const char* chanNames[36][24]={ + {"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6", "Channel 7", "Channel 8", "Channel 9", "Channel 10", "Channel 11", "Channel 12", "Channel 13", "Channel 14", "Channel 15", "Channel 16", "PCM"}, // YMU759/SegaPCM + {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Square 1", "Square 2", "Square 3", "Noise"}, // Genesis + {"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "FM 4", "FM 5", "FM 6", "Square 1", "Square 2", "Square 3", "Noise"}, // Genesis (extended channel 3) + {"Square 1", "Square 2", "Square 3", "Noise"}, // SMS + {"Pulse 1", "Pulse 2", "Wavetable", "Noise"}, // GB + {"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6"}, // PCE/ZX Beeper + {"Pulse 1", "Pulse 2", "Triangle", "Noise", "PCM"}, // NES + {"Channel 1", "Channel 2", "Channel 3"}, // C64 + {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "FM 7", "FM 8", "PCM 1", "PCM 2", "PCM 3", "PCM 4", "PCM 5"}, // Arcade + {"FM 1", "FM 2", "FM 3", "FM 4", "PSG 1", "PSG 2", "PSG 3", "ADPCM-A 1", "ADPCM-A 2", "ADPCM-A 3", "ADPCM-A 4", "ADPCM-A 5", "ADPCM-A 6", "ADPCM-B"}, // YM2610 + {"FM 1", "FM 2 OP1", "FM 2 OP2", "FM 2 OP3", "FM 2 OP4", "FM 3", "FM 4", "PSG 1", "PSG 2", "PSG 3", "ADPCM-A 1", "ADPCM-A 2", "ADPCM-A 3", "ADPCM-A 4", "ADPCM-A 5", "ADPCM-A 6", "ADPCM-B"}, // YM2610 (extended channel 2) + {"PSG 1", "PSG 2", "PSG 3"}, // AY-3-8910 + {"Channel 1", "Channel 2", "Channel 3", "Channel 4"}, // Amiga/POKEY/Swan + {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "FM 7", "FM 8"}, // YM2151/YM2414 + {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6"}, // YM2612 + {"Channel 1", "Channel 2"}, // TIA + {"PSG 1", "PSG 2", "PSG 3", "PSG 4", "PSG 5", "PSG 6"}, // SAA1099 + {"PSG 1", "PSG 2", "PSG 3"}, // AY8930 + {"Low", "Mid", "High", "Noise"}, // VIC-20 + {"Wave"}, // PET + {"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6", "Channel 7", "Channel 8"}, // SNES/N163/RF5C68 + {"VRC6 1", "VRC6 2", "VRC6 Saw"}, // VRC6 + {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "FM 7", "FM 8", "FM 9"}, // OPLL/OPL/OPL2/VRC7 + {"FDS"}, // FDS + {"Pulse 1", "Pulse 2", "PCM"}, // MMC5 + {"FM 1", "FM 2", "FM 3", "PSG 1", "PSG 2", "PSG 3"}, // OPN + {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Square 1", "Square 2", "Square 3", "Kick", "Snare", "Top", "HiHat", "Tom", "Rim", "ADPCM"}, // PC-98 + {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "FM 7", "FM 8", "FM 9", "FM 10", "FM 11", "FM 12", "FM 13", "FM 14", "FM 15", "FM 16", "FM 17", "FM 18"}, // OPL3 + {"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6", "Channel 7", "Channel 8", "Channel 9", "Channel 10", "Channel 11", "Channel 12", "Channel 13", "Channel 14", "Channel 15", "Channel 16", "Channel 17", "Channel 18", "Channel 19", "Channel 20", "Channel 21", "Channel 22", "Channel 23", "Channel 24"}, // MultiPCM + {"Square"}, // PC Speaker/Pokémon Mini + {"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Noise"}, // Virtual Boy/SCC + {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "PSG 1", "PSG 2", "PSG 3", "ADPCM-A 1", "ADPCM-A 2", "ADPCM-A 3", "ADPCM-A 4", "ADPCM-A 5", "ADPCM-A 6", "ADPCM-B"}, // YM2610B + {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Kick", "Snare", "Tom", "Top", "HiHat"}, // OPLL/OPL/OPL2 drums + {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "FM 7", "FM 8", "FM 9", "FM 10", "FM 11", "FM 12", "FM 13", "FM 14", "FM 15", "Kick", "Snare", "Tom", "Top", "HiHat"}, // OPL3 drums + {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "4OP 1", "4OP 2", "4OP 3", "4OP 4", "4OP 5", "4OP 6"}, // OPL3 4-op + {"FM 1", "FM 2", "FM 3", "4OP 1", "4OP 2", "4OP 3", "4OP 4", "4OP 5", "4OP 6", "Kick", "Snare", "Tom", "Top", "HiHat"}, // OPL3 4-op + drums +}; + +const char* chanShortNames[36][24]={ + {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "PCM"}, // YMU759 + {"F1", "F2", "F3", "F4", "F5", "F6", "S1", "S2", "S3", "NO"}, // Genesis + {"F1", "F2", "O1", "O2", "O3", "O4", "F4", "F5", "F6", "S1", "S2", "S3", "S4"}, // Genesis (extended channel 3) + {"S1", "S2", "S3", "NO"}, // SMS + {"S1", "S2", "WA", "NO"}, // GB + {"CH1", "CH2", "CH3", "CH4", "CH5", "CH6"}, // PCE + {"S1", "S2", "TR", "NO", "PCM"}, // NES + {"CH1", "CH2", "CH3"}, // C64 + {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "P1", "P2", "P3", "P4", "P5"}, // Arcade + {"F1", "F2", "F3", "F4", "S1", "S2", "S3", "P1", "P2", "P3", "P4", "P5", "P6", "B"}, // YM2610 + {"F1", "O1", "O2", "O3", "O4", "F3", "F4", "S1", "S2", "S3", "P1", "P2", "P3", "P4", "P5", "P6", "B"}, // YM2610 (extended channel 2) + {"S1", "S2", "S3"}, // AY-3-8910 + {"CH1", "CH2", "CH3", "CH4"}, // Amiga + {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8"}, // YM2151 + {"F1", "F2", "F3", "F4", "F5", "F6"}, // YM2612 + {"CH1", "CH2"}, // TIA + {"S1", "S2", "S3", "S4", "S5", "S6"}, // SAA1099 + {"S1", "S2", "S3"}, // AY8930 + {"LO", "MID", "HI", "NO"}, // VIC-20 + {"PET"}, // PET + {"CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7", "CH8"}, // SNES/N163/RF5C68 + {"V1", "V2", "VS"}, // VRC6 + {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"}, // OPLL/OPL/OPL2/VRC7 + {"FDS"}, // FDS + {"S1", "S2", "PCM"}, // MMC5 + {"F1", "F2", "F3", "S1", "S2", "S3"}, // OPN + {"F1", "F2", "F3", "F4", "F5", "F6", "S1", "S2", "S3", "BD", "SD", "TP", "HH", "TM", "RM", "P"}, // PC-98 + {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18"}, // OPL3 + {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"}, // MultiPCM + {"SQ"}, // PC Speaker/Pokémon Mini + {"CH1", "CH2", "CH3", "CH4", "CH5", "NO"}, // Virtual Boy/SCC + {"F1", "F2", "F3", "F4", "F5", "F6", "S1", "S2", "S3", "P1", "P2", "P3", "P4", "P5", "P6", "B"}, // YM2610B + {"F1", "F2", "F3", "F4", "F5", "F6", "BD", "SD", "TM", "TP", "HH"}, // OPLL/OPL/OPL2 drums + {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "BD", "SD", "TM", "TP", "HH"}, // OPL3 drums + {"F1", "F2", "F3", "F4", "F5", "F6", "Q1", "Q2", "Q3", "Q4", "Q5", "Q6"}, // OPL3 4-op + {"F1", "F2", "F3", "Q1", "Q2", "Q3", "Q4", "Q5", "Q6", "BD", "SD", "TM", "TP", "HH"}, // OPL3 4-op + drums +}; + +const int chanTypes[36][24]={ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4}, // YMU759 + {0, 0, 0, 0, 0, 0, 1, 1, 1, 2}, // Genesis + {0, 0, 5, 5, 5, 5, 0, 0, 0, 1, 1, 1, 2}, // Genesis (extended channel 3) + {1, 1, 1, 2}, // SMS + {1, 1, 3, 2}, // GB + {3, 3, 3, 3, 3, 3}, // PCE + {1, 1, 3, 2, 4}, // NES + {2, 2, 2}, // C64 + {0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4}, // Arcade + {0, 0, 0, 0, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4}, // YM2610 + {0, 5, 5, 5, 5, 0, 0, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4}, // YM2610 (extended channel 2) + {1, 1, 1}, // AY-3-8910 + {4, 4, 4, 4}, // Amiga + {0, 0, 0, 0, 0, 0, 0, 0}, // YM2151 + {0, 0, 0, 0, 0, 0}, // YM2612 + {3, 3}, // TIA + {1, 1, 1, 1, 1, 1}, // SAA1099 + {1, 1, 1}, // AY8930 + {1, 1, 1, 2}, // VIC-20 + {1}, // PET + {4, 4, 4, 4, 4, 4, 4, 4}, // SNES/N163/RF5C68 + {1, 1, 3}, // VRC6 + {0, 0, 0, 0, 0, 0, 0, 0, 0}, // OPLL/OPL/OPL2/VRC7 + {3}, // FDS + {1, 1, 4}, // MMC5 + {0, 0, 0, 1, 1, 1}, // OPN + {0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 4}, // PC-98 + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // OPL3 + {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, // MultiPCM + {1}, // PC Speaker/Pokémon Mini + {3, 3, 3, 3, 3, 2}, // Virtual Boy/SCC + {0, 0, 0, 0, 0, 0, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4}, // YM2610B + {0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2}, // OPLL/OPL/OPL2 drums + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2}, // OPL3 drums + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // OPL3 4-op + {0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2}, // OPL3 4-op + drums +}; + +const DivInstrumentType chanPrefType[42][24]={ + {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM}, // YMU759 + {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_STD, DIV_INS_STD, DIV_INS_STD, DIV_INS_STD}, // Genesis + {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_STD, DIV_INS_STD, DIV_INS_STD, DIV_INS_STD}, // Genesis (extended channel 3) + {DIV_INS_STD, DIV_INS_STD, DIV_INS_STD, DIV_INS_STD}, // SMS + {DIV_INS_GB, DIV_INS_GB, DIV_INS_GB, DIV_INS_GB}, // GB + {DIV_INS_PCE, DIV_INS_PCE, DIV_INS_PCE, DIV_INS_PCE, DIV_INS_PCE, DIV_INS_PCE}, // PCE + {DIV_INS_STD, DIV_INS_STD, DIV_INS_STD, DIV_INS_STD, DIV_INS_STD}, // NES + {DIV_INS_C64, DIV_INS_C64, DIV_INS_C64}, // C64 + {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, // Arcade + {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, // YM2610 + {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, // YM2610 (extended channel 2) + {DIV_INS_AY, DIV_INS_AY, DIV_INS_AY}, // AY-3-8910 + {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, // Amiga + {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM}, // YM2151 + {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM}, // YM2612 + {DIV_INS_TIA, DIV_INS_TIA}, // TIA + {DIV_INS_SAA1099, DIV_INS_SAA1099, DIV_INS_SAA1099, DIV_INS_SAA1099, DIV_INS_SAA1099, DIV_INS_SAA1099}, // SAA1099 + {DIV_INS_AY8930, DIV_INS_AY8930, DIV_INS_AY8930}, // AY8930 + {DIV_INS_VIC, DIV_INS_VIC, DIV_INS_VIC, DIV_INS_VIC}, // VIC-20 + {DIV_INS_PET}, // PET + {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, // SNES/N163/RF5C68 + {DIV_INS_VRC6, DIV_INS_VRC6, DIV_INS_VRC6}, // VRC6 + {DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL}, // OPLL/VRC7 + {DIV_INS_FDS}, // FDS + {DIV_INS_STD, DIV_INS_STD, DIV_INS_AMIGA}, // MMC5 + {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY}, // OPN + {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, // PC-98 + {DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL}, // OPL/OPL2/OPL3 + {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, // MultiPCM + {DIV_INS_STD}, // PC Speaker/Pokémon Mini + {DIV_INS_VBOY, DIV_INS_VBOY, DIV_INS_VBOY, DIV_INS_VBOY, DIV_INS_VBOY, DIV_INS_VBOY}, // Virtual Boy + {DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, // YM2610B + {DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL, DIV_INS_OPLL}, // OPLL drums + {DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL}, // OPL3 drums + {DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ}, // OPL3 4-op + {DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL}, // OPL3 4-op + drums + {DIV_INS_SCC, DIV_INS_SCC, DIV_INS_SCC, DIV_INS_SCC, DIV_INS_SCC}, // SCC + {DIV_INS_N163, DIV_INS_N163, DIV_INS_N163, DIV_INS_N163, DIV_INS_N163, DIV_INS_N163, DIV_INS_N163, DIV_INS_N163}, // N163 + {DIV_INS_POKEY, DIV_INS_POKEY, DIV_INS_POKEY, DIV_INS_POKEY}, // POKEY + {DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER}, // ZX beeper + {DIV_INS_SWAN, DIV_INS_SWAN, DIV_INS_SWAN, DIV_INS_SWAN}, // Swan + {DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ, DIV_INS_OPZ}, // Z +}; + +const char* DivEngine::getChannelName(int chan) { + if (chan<0 || chan>chans) return "??"; + if (!song.chanName[chan].empty()) return song.chanName[chan].c_str(); + switch (sysOfChan[chan]) { + case DIV_SYSTEM_NULL: case DIV_SYSTEM_YMU759: + return chanNames[0][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_GENESIS: + return chanNames[1][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_GENESIS_EXT: + case DIV_SYSTEM_YM2612_EXT: + return chanNames[2][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_SMS: + return chanNames[3][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_GB: + return chanNames[4][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_PCE: + case DIV_SYSTEM_SFX_BEEPER: + return chanNames[5][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_NES: + return chanNames[6][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_C64_6581: case DIV_SYSTEM_C64_8580: + return chanNames[7][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_ARCADE: + case DIV_SYSTEM_OPZ: + return chanNames[8][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2610: + case DIV_SYSTEM_YM2610_FULL: + return chanNames[9][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2610_EXT: + case DIV_SYSTEM_YM2610_FULL_EXT: + return chanNames[10][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_AY8910: + return chanNames[11][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_AMIGA: + case DIV_SYSTEM_POKEY: + case DIV_SYSTEM_SWAN: + return chanNames[12][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2151: + return chanNames[13][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2612: + return chanNames[14][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_TIA: + return chanNames[15][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_VIC20: + return chanNames[18][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_PET: + return chanNames[19][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_SNES: + case DIV_SYSTEM_N163: + case DIV_SYSTEM_RF5C68: + return chanNames[20][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_VRC6: + return chanNames[21][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPLL: + case DIV_SYSTEM_OPL: + case DIV_SYSTEM_OPL2: + case DIV_SYSTEM_VRC7: + return chanNames[22][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_FDS: + return chanNames[23][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_MMC5: + return chanNames[24][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPN: + return chanNames[25][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_PC98: + return chanNames[26][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPL3: + return chanNames[27][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_MULTIPCM: + case DIV_SYSTEM_SEGAPCM: + return chanNames[28][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_PCSPKR: + case DIV_SYSTEM_POKEMINI: + return chanNames[29][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_VBOY: + case DIV_SYSTEM_SCC: + return chanNames[30][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2610B: + return chanNames[31][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPLL_DRUMS: + case DIV_SYSTEM_OPL_DRUMS: + case DIV_SYSTEM_OPL2_DRUMS: + return chanNames[32][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPL3_DRUMS: + return chanNames[33][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_SAA1099: + return chanNames[16][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_AY8930: + return chanNames[17][dispatchChanOfChan[chan]]; + break; + } + return "??"; +} + +const char* DivEngine::getChannelShortName(int chan) { + if (chan<0 || chan>chans) return "??"; + if (!song.chanShortName[chan].empty()) return song.chanShortName[chan].c_str(); + switch (sysOfChan[chan]) { + case DIV_SYSTEM_NULL: case DIV_SYSTEM_YMU759: + return chanShortNames[0][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_GENESIS: + return chanShortNames[1][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_GENESIS_EXT: + case DIV_SYSTEM_YM2612_EXT: + return chanShortNames[2][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_SMS: + return chanShortNames[3][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_GB: + return chanShortNames[4][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_PCE: + case DIV_SYSTEM_SFX_BEEPER: + return chanShortNames[5][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_NES: + return chanShortNames[6][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_C64_6581: case DIV_SYSTEM_C64_8580: + return chanShortNames[7][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_ARCADE: + case DIV_SYSTEM_OPZ: + return chanShortNames[8][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2610: + case DIV_SYSTEM_YM2610_FULL: + return chanShortNames[9][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2610_EXT: + case DIV_SYSTEM_YM2610_FULL_EXT: + return chanShortNames[10][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_AY8910: + return chanShortNames[11][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_AMIGA: + case DIV_SYSTEM_POKEY: + case DIV_SYSTEM_SWAN: + return chanShortNames[12][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2151: + return chanShortNames[13][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2612: + return chanShortNames[14][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_TIA: + return chanShortNames[15][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_VIC20: + return chanShortNames[18][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_PET: + return chanShortNames[19][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_SNES: + case DIV_SYSTEM_N163: + case DIV_SYSTEM_RF5C68: + return chanShortNames[20][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_VRC6: + return chanShortNames[21][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPLL: + case DIV_SYSTEM_OPL: + case DIV_SYSTEM_OPL2: + case DIV_SYSTEM_VRC7: + return chanShortNames[22][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_FDS: + return chanShortNames[23][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_MMC5: + return chanShortNames[24][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPN: + return chanShortNames[25][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_PC98: + return chanShortNames[26][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPL3: + return chanShortNames[27][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_MULTIPCM: + case DIV_SYSTEM_SEGAPCM: + return chanShortNames[28][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_PCSPKR: + case DIV_SYSTEM_POKEMINI: + return chanShortNames[29][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_VBOY: + case DIV_SYSTEM_SCC: + return chanShortNames[30][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2610B: + return chanShortNames[31][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPLL_DRUMS: + case DIV_SYSTEM_OPL_DRUMS: + case DIV_SYSTEM_OPL2_DRUMS: + return chanShortNames[32][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPL3_DRUMS: + return chanShortNames[33][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_SAA1099: + return chanShortNames[16][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_AY8930: + return chanShortNames[17][dispatchChanOfChan[chan]]; + break; + } + return "??"; +} + +int DivEngine::getChannelType(int chan) { + switch (sysOfChan[chan]) { + case DIV_SYSTEM_NULL: case DIV_SYSTEM_YMU759: + return chanTypes[0][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_GENESIS: + return chanTypes[1][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_GENESIS_EXT: + case DIV_SYSTEM_YM2612_EXT: + return chanTypes[2][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_SMS: + return chanTypes[3][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_GB: + return chanTypes[4][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_PCE: + case DIV_SYSTEM_SFX_BEEPER: + return chanTypes[5][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_NES: + return chanTypes[6][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_C64_6581: case DIV_SYSTEM_C64_8580: + return chanTypes[7][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_ARCADE: + case DIV_SYSTEM_OPZ: + return chanTypes[8][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2610: + case DIV_SYSTEM_YM2610_FULL: + return chanTypes[9][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2610_EXT: + case DIV_SYSTEM_YM2610_FULL_EXT: + return chanTypes[10][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_AY8910: + return chanTypes[11][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_AMIGA: + case DIV_SYSTEM_POKEY: + case DIV_SYSTEM_SWAN: + return chanTypes[12][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2151: + return chanTypes[13][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2612: + return chanTypes[14][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_TIA: + return chanTypes[15][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_VIC20: + return chanTypes[18][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_PET: + return chanTypes[19][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_SNES: + case DIV_SYSTEM_N163: + case DIV_SYSTEM_RF5C68: + return chanTypes[20][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_VRC6: + return chanTypes[21][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPLL: + case DIV_SYSTEM_OPL: + case DIV_SYSTEM_OPL2: + case DIV_SYSTEM_VRC7: + return chanTypes[22][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_FDS: + return chanTypes[23][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_MMC5: + return chanTypes[24][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPN: + return chanTypes[25][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_PC98: + return chanTypes[26][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPL3: + return chanTypes[27][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_MULTIPCM: + case DIV_SYSTEM_SEGAPCM: + return chanTypes[28][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_PCSPKR: + case DIV_SYSTEM_POKEMINI: + return chanTypes[29][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_VBOY: + case DIV_SYSTEM_SCC: + return chanTypes[30][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2610B: + return chanTypes[31][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPLL_DRUMS: + case DIV_SYSTEM_OPL_DRUMS: + case DIV_SYSTEM_OPL2_DRUMS: + return chanTypes[32][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPL3_DRUMS: + return chanTypes[33][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_SAA1099: + return chanTypes[16][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_AY8930: + return chanTypes[17][dispatchChanOfChan[chan]]; + break; + } + return 1; +} + +DivInstrumentType DivEngine::getPreferInsType(int chan) { + switch (sysOfChan[chan]) { + case DIV_SYSTEM_NULL: case DIV_SYSTEM_YMU759: + return chanPrefType[0][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_GENESIS: + return chanPrefType[1][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_GENESIS_EXT: + case DIV_SYSTEM_YM2612_EXT: + return chanPrefType[2][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_SMS: + return chanPrefType[3][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_GB: + return chanPrefType[4][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_PCE: + return chanPrefType[5][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_NES: + return chanPrefType[6][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_C64_6581: case DIV_SYSTEM_C64_8580: + return chanPrefType[7][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_ARCADE: + return chanPrefType[8][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2610: + case DIV_SYSTEM_YM2610_FULL: + return chanPrefType[9][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2610_EXT: + case DIV_SYSTEM_YM2610_FULL_EXT: + return chanPrefType[10][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_AY8910: + return chanPrefType[11][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_AMIGA: + return chanPrefType[12][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2151: + return chanPrefType[13][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2612: + return chanPrefType[14][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_TIA: + return chanPrefType[15][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_VIC20: + return chanPrefType[18][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_PET: + return chanPrefType[19][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_SNES: + case DIV_SYSTEM_RF5C68: + return chanPrefType[20][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_VRC6: + return chanPrefType[21][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPLL: + case DIV_SYSTEM_VRC7: + return chanPrefType[22][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_FDS: + return chanPrefType[23][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_MMC5: + return chanPrefType[24][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPN: + return chanPrefType[25][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_PC98: + return chanPrefType[26][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPL: + case DIV_SYSTEM_OPL2: + case DIV_SYSTEM_OPL3: + return chanPrefType[27][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_MULTIPCM: + case DIV_SYSTEM_SEGAPCM: + return chanPrefType[28][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_PCSPKR: + case DIV_SYSTEM_POKEMINI: + return chanPrefType[29][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_VBOY: + return chanPrefType[30][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_SCC: + return chanPrefType[36][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_N163: + return chanPrefType[37][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_YM2610B: + return chanPrefType[31][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPLL_DRUMS: + return chanPrefType[32][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPL_DRUMS: + case DIV_SYSTEM_OPL2_DRUMS: + case DIV_SYSTEM_OPL3_DRUMS: + return chanPrefType[33][dispatchChanOfChan[chan]]; + return chanPrefType[33][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_SAA1099: + return chanPrefType[16][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_AY8930: + return chanPrefType[17][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_POKEY: + return chanPrefType[38][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_SFX_BEEPER: + return chanPrefType[39][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_SWAN: + return chanPrefType[40][dispatchChanOfChan[chan]]; + break; + case DIV_SYSTEM_OPZ: + return chanPrefType[41][dispatchChanOfChan[chan]]; + break; + } + return DIV_INS_FM; +} + +bool DivEngine::isVGMExportable(DivSystem which) { + switch (which) { + case DIV_SYSTEM_GENESIS: + case DIV_SYSTEM_GENESIS_EXT: + case DIV_SYSTEM_SMS: + case DIV_SYSTEM_GB: + case DIV_SYSTEM_PCE: + case DIV_SYSTEM_NES: + case DIV_SYSTEM_ARCADE: + case DIV_SYSTEM_YM2151: + case DIV_SYSTEM_YM2612: + case DIV_SYSTEM_YM2610: + case DIV_SYSTEM_YM2610_EXT: + case DIV_SYSTEM_AY8910: + case DIV_SYSTEM_AY8930: + case DIV_SYSTEM_SAA1099: + return true; + default: + return false; + } + return false; +}