giga-refactor, part 14 - READ

a new way to define chip channels has been introduced, replacing the old one.
it looks cleaner and is more flexible (even supporting dynamic channel count).

it works by defining a function in the chip definition, which returns a DivChanDef with channel information (name, short name, type and instrument type(s)).
alternatively, a list can be provided in the DivChanDefFunc() constructor, in the event channels differ greatly and/or the number of channels is small.

some helper templates, such as stockChanDef and simpleChanDef also exist, which automatically map channel names and types regardless of count.
This commit is contained in:
tildearrow 2025-11-17 19:38:45 -05:00
parent 8497024079
commit 9b35ca77c5
6 changed files with 1171 additions and 815 deletions

View file

@ -27,6 +27,7 @@
#include "export.h"
#include "dataErrors.h"
#include "safeWriter.h"
#include "sysDef.h"
#include "cmdStream.h"
#include "filePlayer.h"
#include "../audio/taAudio.h"
@ -332,131 +333,6 @@ struct DivEffectContainer {
}
};
typedef int EffectValConversion(unsigned char,unsigned char);
struct EffectHandler {
DivDispatchCmds dispatchCmd;
const char* description;
EffectValConversion* val;
EffectValConversion* val2;
EffectHandler(
DivDispatchCmds dispatchCmd_,
const char* description_,
EffectValConversion val_=NULL,
EffectValConversion val2_=NULL
):
dispatchCmd(dispatchCmd_),
description(description_),
val(val_),
val2(val2_) {}
};
struct DivDoNotHandleEffect {
};
typedef std::unordered_map<unsigned char,const EffectHandler> EffectHandlerMap;
struct DivSysDef {
const char* name;
const char* nameJ;
const char* description;
unsigned char id;
unsigned char id_DMF;
int channels, minChans, maxChans;
bool isFM, isSTD, isCompound;
// width 0: variable
// height 0: no wavetable support
unsigned short waveWidth, waveHeight;
unsigned int vgmVersion;
unsigned int sampleFormatMask;
const char* chanNames[DIV_MAX_CHANS];
const char* chanShortNames[DIV_MAX_CHANS];
int chanTypes[DIV_MAX_CHANS];
// 0: primary
// 1: alternate (usually PCM)
DivInstrumentType chanInsType[DIV_MAX_CHANS][2];
const EffectHandlerMap effectHandlers;
const EffectHandlerMap postEffectHandlers;
const EffectHandlerMap preEffectHandlers;
DivSysDef(
const char* sysName, const char* sysNameJ, unsigned char fileID, unsigned char fileID_DMF, int chans, int minCh, int maxCh,
bool isFMChip, bool isSTDChip, unsigned int vgmVer, bool compound, unsigned int formatMask, unsigned short waveWid, unsigned short waveHei,
const char* desc,
std::initializer_list<const char*> chNames,
std::initializer_list<const char*> chShortNames,
std::initializer_list<int> chTypes,
std::initializer_list<DivInstrumentType> chInsType1,
std::initializer_list<DivInstrumentType> chInsType2={},
const EffectHandlerMap fxHandlers_={},
const EffectHandlerMap postFxHandlers_={},
const EffectHandlerMap preFxHandlers_={}):
name(sysName),
nameJ(sysNameJ),
description(desc),
id(fileID),
id_DMF(fileID_DMF),
channels(chans),
minChans(minCh),
maxChans(maxCh),
isFM(isFMChip),
isSTD(isSTDChip),
isCompound(compound),
waveWidth(waveWid),
waveHeight(waveHei),
vgmVersion(vgmVer),
sampleFormatMask(formatMask),
effectHandlers(fxHandlers_),
postEffectHandlers(postFxHandlers_),
preEffectHandlers(preFxHandlers_) {
memset(chanNames,0,DIV_MAX_CHANS*sizeof(void*));
memset(chanShortNames,0,DIV_MAX_CHANS*sizeof(void*));
memset(chanTypes,0,DIV_MAX_CHANS*sizeof(int));
for (int i=0; i<DIV_MAX_CHANS; i++) {
chanInsType[i][0]=DIV_INS_NULL;
chanInsType[i][1]=DIV_INS_NULL;
}
int index=0;
for (const char* i: chNames) {
chanNames[index++]=i;
if (index>=DIV_MAX_CHANS) break;
}
index=0;
for (const char* i: chShortNames) {
chanShortNames[index++]=i;
if (index>=DIV_MAX_CHANS) break;
}
index=0;
for (int i: chTypes) {
chanTypes[index++]=i;
if (index>=DIV_MAX_CHANS) break;
}
index=0;
for (DivInstrumentType i: chInsType1) {
chanInsType[index++][0]=i;
if (index>=DIV_MAX_CHANS) break;
}
index=0;
for (DivInstrumentType i: chInsType2) {
chanInsType[index++][1]=i;
if (index>=DIV_MAX_CHANS) break;
}
}
};
enum DivChanTypes {
DIV_CH_FM=0,
DIV_CH_PULSE=1,
DIV_CH_NOISE=2,
DIV_CH_WAVE=3,
DIV_CH_PCM=4,
DIV_CH_OP=5
};
extern const char* cmdName[];
class DivEngine {

View file

@ -928,17 +928,20 @@ void DivSong::recalcChans() {
dispatchChanOfChan[chanIndex]=-1;
}
dispatchFirstChan[chanIndex]=firstChan;
chanIndex++;
if (sysDef!=NULL) {
if (sysDef->chanInsType[j][0]!=DIV_INS_NULL) {
isInsTypePossible[sysDef->chanInsType[j][0]]=true;
chanDef[chanIndex]=sysDef->getChanDef(j);
if (chanDef[chanIndex].insType[0]!=DIV_INS_NULL) {
isInsTypePossible[chanDef[chanIndex].insType[0]]=true;
}
if (sysDef->chanInsType[j][1]!=DIV_INS_NULL) {
isInsTypePossible[sysDef->chanInsType[j][1]]=true;
if (chanDef[chanIndex].insType[1]!=DIV_INS_NULL) {
isInsTypePossible[chanDef[chanIndex].insType[1]]=true;
}
} else {
chanDef[chanIndex]=DivChanDef();
}
chanIndex++;
}
}

View file

@ -32,125 +32,7 @@
#include "pattern.h"
#include "wavetable.h"
#include "sample.h"
enum DivSystem {
DIV_SYSTEM_NULL=0,
DIV_SYSTEM_YMU759,
DIV_SYSTEM_GENESIS, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_GENESIS_EXT, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_SMS,
DIV_SYSTEM_SMS_OPLL, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_GB,
DIV_SYSTEM_PCE,
DIV_SYSTEM_NES,
DIV_SYSTEM_NES_VRC7, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_NES_FDS, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_C64_6581,
DIV_SYSTEM_C64_8580,
DIV_SYSTEM_ARCADE, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_MSX2, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_YM2610,
DIV_SYSTEM_YM2610_EXT,
DIV_SYSTEM_AY8910,
DIV_SYSTEM_AMIGA,
DIV_SYSTEM_YM2151,
DIV_SYSTEM_YM2612,
DIV_SYSTEM_TIA,
DIV_SYSTEM_SAA1099,
DIV_SYSTEM_AY8930,
DIV_SYSTEM_VIC20,
DIV_SYSTEM_PET,
DIV_SYSTEM_SNES,
DIV_SYSTEM_VRC6,
DIV_SYSTEM_OPLL,
DIV_SYSTEM_FDS,
DIV_SYSTEM_MMC5,
DIV_SYSTEM_N163,
DIV_SYSTEM_YM2203,
DIV_SYSTEM_YM2203_EXT,
DIV_SYSTEM_YM2608,
DIV_SYSTEM_YM2608_EXT,
DIV_SYSTEM_OPL,
DIV_SYSTEM_OPL2,
DIV_SYSTEM_OPL3,
DIV_SYSTEM_MULTIPCM,
DIV_SYSTEM_PCSPKR,
DIV_SYSTEM_POKEY,
DIV_SYSTEM_RF5C68,
DIV_SYSTEM_SWAN,
DIV_SYSTEM_OPZ,
DIV_SYSTEM_POKEMINI,
DIV_SYSTEM_SEGAPCM,
DIV_SYSTEM_VBOY,
DIV_SYSTEM_VRC7,
DIV_SYSTEM_YM2610B,
DIV_SYSTEM_SFX_BEEPER,
DIV_SYSTEM_SFX_BEEPER_QUADTONE,
DIV_SYSTEM_YM2612_EXT,
DIV_SYSTEM_SCC,
DIV_SYSTEM_OPL_DRUMS,
DIV_SYSTEM_OPL2_DRUMS,
DIV_SYSTEM_OPL3_DRUMS,
DIV_SYSTEM_YM2610_FULL,
DIV_SYSTEM_YM2610_FULL_EXT,
DIV_SYSTEM_OPLL_DRUMS,
DIV_SYSTEM_LYNX,
DIV_SYSTEM_QSOUND,
DIV_SYSTEM_VERA,
DIV_SYSTEM_YM2610B_EXT,
DIV_SYSTEM_SEGAPCM_COMPAT,
DIV_SYSTEM_X1_010,
DIV_SYSTEM_BUBSYS_WSG,
DIV_SYSTEM_OPL4,
DIV_SYSTEM_OPL4_DRUMS,
DIV_SYSTEM_ES5506,
DIV_SYSTEM_Y8950,
DIV_SYSTEM_Y8950_DRUMS,
DIV_SYSTEM_SCC_PLUS,
DIV_SYSTEM_SOUND_UNIT,
DIV_SYSTEM_MSM6295,
DIV_SYSTEM_MSM6258,
DIV_SYSTEM_YMZ280B,
DIV_SYSTEM_NAMCO,
DIV_SYSTEM_NAMCO_15XX,
DIV_SYSTEM_NAMCO_CUS30,
DIV_SYSTEM_YM2612_DUALPCM,
DIV_SYSTEM_YM2612_DUALPCM_EXT,
DIV_SYSTEM_MSM5232,
DIV_SYSTEM_T6W28,
DIV_SYSTEM_K007232,
DIV_SYSTEM_GA20,
DIV_SYSTEM_PCM_DAC,
DIV_SYSTEM_PONG,
DIV_SYSTEM_DUMMY,
DIV_SYSTEM_YM2612_CSM,
DIV_SYSTEM_YM2610_CSM,
DIV_SYSTEM_YM2610B_CSM,
DIV_SYSTEM_YM2203_CSM,
DIV_SYSTEM_YM2608_CSM,
DIV_SYSTEM_SM8521,
DIV_SYSTEM_PV1000,
DIV_SYSTEM_K053260,
DIV_SYSTEM_TED,
DIV_SYSTEM_C140,
DIV_SYSTEM_C219,
DIV_SYSTEM_ESFM,
DIV_SYSTEM_POWERNOISE,
DIV_SYSTEM_DAVE,
DIV_SYSTEM_NDS,
DIV_SYSTEM_GBA_DMA,
DIV_SYSTEM_GBA_MINMOD,
DIV_SYSTEM_5E01,
DIV_SYSTEM_BIFURCATOR,
DIV_SYSTEM_SID2,
DIV_SYSTEM_SUPERVISION,
DIV_SYSTEM_UPD1771C,
DIV_SYSTEM_SID3,
DIV_SYSTEM_C64_PCM,
DIV_SYSTEM_MAX
};
#include "sysDef.h"
enum DivEffectType: unsigned short {
DIV_EFFECT_NULL=0,
@ -463,6 +345,8 @@ struct DivSong {
int dispatchChanOfChan[DIV_MAX_CHANS];
// the first channel of a chip, indexed per channel
int dispatchFirstChan[DIV_MAX_CHANS];
// cached DivChanDef for each channel.
DivChanDef chanDef[DIV_MAX_CHANS];
std::vector<DivInstrumentType> possibleInsTypes;

File diff suppressed because it is too large Load diff

272
src/engine/sysDef.h Normal file
View file

@ -0,0 +1,272 @@
/**
* Furnace Tracker - multi-system chiptune tracker
* Copyright (C) 2021-2025 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.
*/
#ifndef _SYS_DEF_H
#define _SYS_DEF_H
#include "dispatch.h"
#include "instrument.h"
#include <functional>
#include <initializer_list>
typedef int EffectValConversion(unsigned char,unsigned char);
struct EffectHandler {
DivDispatchCmds dispatchCmd;
const char* description;
EffectValConversion* val;
EffectValConversion* val2;
EffectHandler(
DivDispatchCmds dispatchCmd_,
const char* description_,
EffectValConversion val_=NULL,
EffectValConversion val2_=NULL
):
dispatchCmd(dispatchCmd_),
description(description_),
val(val_),
val2(val2_) {}
};
struct DivDoNotHandleEffect {
};
typedef std::unordered_map<unsigned char,const EffectHandler> EffectHandlerMap;
enum DivChanTypes {
DIV_CH_FM=0,
DIV_CH_PULSE=1,
DIV_CH_NOISE=2,
DIV_CH_WAVE=3,
DIV_CH_PCM=4,
DIV_CH_OP=5
};
struct DivChanDef {
String name;
String shortName;
int type;
// 0: primary
// 1: alternate (usually PCM)
DivInstrumentType insType[2];
DivChanDef(const String& n, const String& sn, int t, DivInstrumentType insT, DivInstrumentType insT2=DIV_INS_NULL):
name(n),
shortName(sn),
type(t),
insType{insT,insT2} {}
DivChanDef():
name("??"),
shortName("??"),
type(DIV_CH_NOISE),
insType{DIV_INS_NULL,DIV_INS_NULL} {}
};
struct DivChanDefFunc {
std::vector<DivChanDef> list;
std::function<DivChanDef(unsigned short)> func;
DivChanDef operator()(int& ch) const {
if (ch<0) {
return DivChanDef("??","??",DIV_CH_NOISE,DIV_INS_NULL);
}
if (ch<(int)list.size()) return list[ch];
if (func==NULL) {
return DivChanDef("??","??",DIV_CH_NOISE,DIV_INS_NULL);
}
return func(ch);
}
DivChanDefFunc(std::initializer_list<DivChanDef> l):
list(l), func(NULL) {}
DivChanDefFunc(std::function<DivChanDef(unsigned short)> f):
list(), func(f) {}
DivChanDefFunc():
list(), func(NULL) {}
};
struct DivSysDef {
const char* name;
const char* nameJ;
const char* description;
unsigned char id;
unsigned char id_DMF;
int channels, minChans, maxChans;
bool isFM, isSTD, isCompound;
// width 0: variable
// height 0: no wavetable support
unsigned short waveWidth, waveHeight;
unsigned int vgmVersion;
unsigned int sampleFormatMask;
DivChanDefFunc getChanDef;
const EffectHandlerMap effectHandlers;
const EffectHandlerMap postEffectHandlers;
const EffectHandlerMap preEffectHandlers;
DivSysDef(
const char* sysName, const char* sysNameJ, unsigned char fileID, unsigned char fileID_DMF, int chans, int minCh, int maxCh,
bool isFMChip, bool isSTDChip, unsigned int vgmVer, bool compound, unsigned int formatMask, unsigned short waveWid, unsigned short waveHei,
const char* desc,
DivChanDefFunc gcdFunc,
const EffectHandlerMap fxHandlers_={},
const EffectHandlerMap postFxHandlers_={},
const EffectHandlerMap preFxHandlers_={}):
name(sysName),
nameJ(sysNameJ),
description(desc),
id(fileID),
id_DMF(fileID_DMF),
channels(chans),
minChans(minCh),
maxChans(maxCh),
isFM(isFMChip),
isSTD(isSTDChip),
isCompound(compound),
waveWidth(waveWid),
waveHeight(waveHei),
vgmVersion(vgmVer),
sampleFormatMask(formatMask),
getChanDef(gcdFunc),
effectHandlers(fxHandlers_),
postEffectHandlers(postFxHandlers_),
preEffectHandlers(preFxHandlers_) {
}
};
enum DivSystem {
DIV_SYSTEM_NULL=0,
DIV_SYSTEM_YMU759,
DIV_SYSTEM_GENESIS, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_GENESIS_EXT, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_SMS,
DIV_SYSTEM_SMS_OPLL, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_GB,
DIV_SYSTEM_PCE,
DIV_SYSTEM_NES,
DIV_SYSTEM_NES_VRC7, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_NES_FDS, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_C64_6581,
DIV_SYSTEM_C64_8580,
DIV_SYSTEM_ARCADE, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_MSX2, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_YM2610,
DIV_SYSTEM_YM2610_EXT,
DIV_SYSTEM_AY8910,
DIV_SYSTEM_AMIGA,
DIV_SYSTEM_YM2151,
DIV_SYSTEM_YM2612,
DIV_SYSTEM_TIA,
DIV_SYSTEM_SAA1099,
DIV_SYSTEM_AY8930,
DIV_SYSTEM_VIC20,
DIV_SYSTEM_PET,
DIV_SYSTEM_SNES,
DIV_SYSTEM_VRC6,
DIV_SYSTEM_OPLL,
DIV_SYSTEM_FDS,
DIV_SYSTEM_MMC5,
DIV_SYSTEM_N163,
DIV_SYSTEM_YM2203,
DIV_SYSTEM_YM2203_EXT,
DIV_SYSTEM_YM2608,
DIV_SYSTEM_YM2608_EXT,
DIV_SYSTEM_OPL,
DIV_SYSTEM_OPL2,
DIV_SYSTEM_OPL3,
DIV_SYSTEM_MULTIPCM,
DIV_SYSTEM_PCSPKR,
DIV_SYSTEM_POKEY,
DIV_SYSTEM_RF5C68,
DIV_SYSTEM_SWAN,
DIV_SYSTEM_OPZ,
DIV_SYSTEM_POKEMINI,
DIV_SYSTEM_SEGAPCM,
DIV_SYSTEM_VBOY,
DIV_SYSTEM_VRC7,
DIV_SYSTEM_YM2610B,
DIV_SYSTEM_SFX_BEEPER,
DIV_SYSTEM_SFX_BEEPER_QUADTONE,
DIV_SYSTEM_YM2612_EXT,
DIV_SYSTEM_SCC,
DIV_SYSTEM_OPL_DRUMS,
DIV_SYSTEM_OPL2_DRUMS,
DIV_SYSTEM_OPL3_DRUMS,
DIV_SYSTEM_YM2610_FULL,
DIV_SYSTEM_YM2610_FULL_EXT,
DIV_SYSTEM_OPLL_DRUMS,
DIV_SYSTEM_LYNX,
DIV_SYSTEM_QSOUND,
DIV_SYSTEM_VERA,
DIV_SYSTEM_YM2610B_EXT,
DIV_SYSTEM_SEGAPCM_COMPAT,
DIV_SYSTEM_X1_010,
DIV_SYSTEM_BUBSYS_WSG,
DIV_SYSTEM_OPL4,
DIV_SYSTEM_OPL4_DRUMS,
DIV_SYSTEM_ES5506,
DIV_SYSTEM_Y8950,
DIV_SYSTEM_Y8950_DRUMS,
DIV_SYSTEM_SCC_PLUS,
DIV_SYSTEM_SOUND_UNIT,
DIV_SYSTEM_MSM6295,
DIV_SYSTEM_MSM6258,
DIV_SYSTEM_YMZ280B,
DIV_SYSTEM_NAMCO,
DIV_SYSTEM_NAMCO_15XX,
DIV_SYSTEM_NAMCO_CUS30,
DIV_SYSTEM_YM2612_DUALPCM,
DIV_SYSTEM_YM2612_DUALPCM_EXT,
DIV_SYSTEM_MSM5232,
DIV_SYSTEM_T6W28,
DIV_SYSTEM_K007232,
DIV_SYSTEM_GA20,
DIV_SYSTEM_PCM_DAC,
DIV_SYSTEM_PONG,
DIV_SYSTEM_DUMMY,
DIV_SYSTEM_YM2612_CSM,
DIV_SYSTEM_YM2610_CSM,
DIV_SYSTEM_YM2610B_CSM,
DIV_SYSTEM_YM2203_CSM,
DIV_SYSTEM_YM2608_CSM,
DIV_SYSTEM_SM8521,
DIV_SYSTEM_PV1000,
DIV_SYSTEM_K053260,
DIV_SYSTEM_TED,
DIV_SYSTEM_C140,
DIV_SYSTEM_C219,
DIV_SYSTEM_ESFM,
DIV_SYSTEM_POWERNOISE,
DIV_SYSTEM_DAVE,
DIV_SYSTEM_NDS,
DIV_SYSTEM_GBA_DMA,
DIV_SYSTEM_GBA_MINMOD,
DIV_SYSTEM_5E01,
DIV_SYSTEM_BIFURCATOR,
DIV_SYSTEM_SID2,
DIV_SYSTEM_SUPERVISION,
DIV_SYSTEM_UPD1771C,
DIV_SYSTEM_SID3,
DIV_SYSTEM_C64_PCM,
DIV_SYSTEM_MAX
};
#endif

View file

@ -312,12 +312,14 @@ float FurnaceGUI::drawSystemChannelInfo(const DivSysDef* whichDef, int keyHitOff
if (ledSize.x<8.0f*dpiScale) ledSize.x=8.0f*dpiScale;
float x=p.x, y=p.y;
for (int i=0; i<chanCount; i++) {
DivChanDef chanDef=whichDef->getChanDef(i);
if (x+ledSize.x-0.125>tooltipWidth+p.x) {
x=p.x;
y+=ledSize.y+sep.y;
}
ImVec4 color=uiColors[GUI_COLOR_CHANNEL_BG];
if (i<whichDef->channels) color=uiColors[whichDef->chanTypes[i]+GUI_COLOR_CHANNEL_FM];
if (i<whichDef->channels) color=uiColors[chanDef.type+GUI_COLOR_CHANNEL_FM];
if (keyHitOffset>=0) {
if (e->isChannelMuted(keyHitOffset+i)) {
color=uiColors[GUI_COLOR_CHANNEL_MUTED];
@ -345,7 +347,8 @@ void FurnaceGUI::drawSystemChannelInfoText(const DivSysDef* whichDef) {
memset(chanCount,0,CHANNEL_TYPE_MAX);
// count channel types
for (int i=0; i<whichDef->channels; i++) {
switch (whichDef->chanInsType[i][0]) {
DivChanDef chanDef=whichDef->getChanDef(i);
switch (chanDef.insType[0]) {
case DIV_INS_STD: // square
case DIV_INS_BEEPER:
case DIV_INS_TED:
@ -360,17 +363,17 @@ void FurnaceGUI::drawSystemChannelInfoText(const DivSysDef* whichDef) {
chanCount[CHANNEL_TYPE_PULSE]++;
break;
}
if (whichDef->chanTypes[i]==DIV_CH_NOISE) { // sn/t6w noise
if (chanDef.type==DIV_CH_NOISE) { // sn/t6w noise
chanCount[CHANNEL_TYPE_NOISE]++;
} else { // DIV_CH_PULSE, any sqr chan
chanCount[CHANNEL_TYPE_SQUARE]++;
}
break;
case DIV_INS_NES:
if (whichDef->chanTypes[i]==DIV_CH_WAVE) {
if (chanDef.type==DIV_CH_WAVE) {
chanCount[whichDef->id==0xf1?CHANNEL_TYPE_WAVE:CHANNEL_TYPE_TRIANGLE]++; // triangle, wave for 5E01
} else {
chanCount[whichDef->chanTypes[i]]++;
chanCount[chanDef.type]++;
}
break;
case DIV_INS_AY:
@ -380,23 +383,23 @@ void FurnaceGUI::drawSystemChannelInfoText(const DivSysDef* whichDef) {
case DIV_INS_OPL_DRUMS:
case DIV_INS_OPL:
case DIV_INS_OPLL:
if (whichDef->chanTypes[i]==DIV_CH_OP) {
if (chanDef.type==DIV_CH_OP) {
chanCount[CHANNEL_TYPE_FM]++; // opl3 4op
break;
}
if (whichDef->chanTypes[i]==DIV_CH_NOISE) {
if (chanDef.type==DIV_CH_NOISE) {
chanCount[CHANNEL_TYPE_DRUMS]++; // drums
} else {
chanCount[whichDef->chanTypes[i]]++;
chanCount[chanDef.type]++;
}
break;
case DIV_INS_FM:
if (whichDef->chanTypes[i]==DIV_CH_OP) {
if (chanDef.type==DIV_CH_OP) {
chanCount[CHANNEL_TYPE_OPERATOR]++; // ext. ops
} else if (whichDef->chanTypes[i]==DIV_CH_NOISE) {
} else if (chanDef.type==DIV_CH_NOISE) {
break; // csm timer
} else {
chanCount[whichDef->chanTypes[i]]++;
chanCount[chanDef.type]++;
}
break;
case DIV_INS_ADPCMA:
@ -413,33 +416,33 @@ void FurnaceGUI::drawSystemChannelInfoText(const DivSysDef* whichDef) {
chanCount[CHANNEL_TYPE_SAMPLE]++;
break;
case DIV_INS_NDS:
if (whichDef->chanTypes[i]!=DIV_CH_PCM) { // the psg chans can also play samples??
if (chanDef.type!=DIV_CH_PCM) { // the psg chans can also play samples??
chanCount[CHANNEL_TYPE_SAMPLE]++;
}
chanCount[whichDef->chanTypes[i]]++;
chanCount[chanDef.type]++;
break;
case DIV_INS_VERA:
if (whichDef->chanTypes[i]==DIV_CH_PULSE) {
if (chanDef.type==DIV_CH_PULSE) {
chanCount[CHANNEL_TYPE_WAVE]++;
} else { // sample chan
chanCount[CHANNEL_TYPE_SAMPLE]++;
}
break;
case DIV_INS_DAVE:
if (whichDef->chanTypes[i]==DIV_CH_WAVE) {
if (chanDef.type==DIV_CH_WAVE) {
chanCount[CHANNEL_TYPE_OTHER]++;
} else {
chanCount[whichDef->chanTypes[i]]++;
chanCount[chanDef.type]++;
}
break;
case DIV_INS_SWAN:
if (whichDef->chanTypes[i]!=DIV_CH_WAVE) {
if (chanDef.type!=DIV_CH_WAVE) {
chanCount[CHANNEL_TYPE_WAVETABLE]++;
}
chanCount[whichDef->chanTypes[i]]++;
chanCount[chanDef.type]++;
break;
case DIV_INS_SID3:
if (whichDef->chanTypes[i]!=DIV_CH_WAVE) {
if (chanDef.type!=DIV_CH_WAVE) {
chanCount[CHANNEL_TYPE_OTHER]++;
} else {
chanCount[CHANNEL_TYPE_WAVE]++;
@ -456,7 +459,7 @@ void FurnaceGUI::drawSystemChannelInfoText(const DivSysDef* whichDef) {
chanCount[CHANNEL_TYPE_OTHER]++;
break;
default:
chanCount[whichDef->chanTypes[i]]++;
chanCount[chanDef.type]++;
break;
}
}