From 5bde25cf2fc2258c6bb9254cf4eab0ad3be24511 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 13 Nov 2025 01:39:21 -0500 Subject: [PATCH] giga-refactor, part 5 --- src/engine/fileOps/ftm.cpp | 27 +++++++++++++++++---------- src/engine/song.h | 12 +++++++++++- src/gui/gui.h | 2 +- src/gui/sysManager.cpp | 4 ++-- src/gui/sysMiscInfo.cpp | 12 ++++++++---- 5 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/engine/fileOps/ftm.cpp b/src/engine/fileOps/ftm.cpp index b2df53798..daf27cb4e 100644 --- a/src/engine/fileOps/ftm.cpp +++ b/src/engine/fileOps/ftm.cpp @@ -654,6 +654,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si int curr_chan = 0; int map_ch = 0; + ds.systemChans[systemID]=5; ds.system[systemID++] = DIV_SYSTEM_NES; ds.systemFlags[0].set("resetSweep",true); // FamiTracker behavior @@ -668,6 +669,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si } if (expansions & 1) { + ds.systemChans[systemID]=3; ds.system[systemID++] = DIV_SYSTEM_VRC6; for (int ch = 0; ch < 3; ch++) { @@ -685,6 +687,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si vrc6_saw_chan = map_ch - 1; } if (expansions & 8) { + ds.systemChans[systemID]=3; ds.system[systemID++] = DIV_SYSTEM_MMC5; for (int ch = 0; ch < (eft ? 3 : 2); ch++) { @@ -707,6 +710,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si if (expansions & 16) { ds.system[systemID] = DIV_SYSTEM_N163; ds.systemFlags[systemID].set("channels", (int)n163Chans - 1); + ds.systemChans[systemID]=CLAMP(n163Chans,1,8); systemID++; for (int ch = 0; ch < (int)n163Chans; ch++) { @@ -716,12 +720,13 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si map_ch++; } - for (int ch = 0; ch < (8 - (int)n163Chans); ch++) { + /*for (int ch = 0; ch < (8 - (int)n163Chans); ch++) { map_channels[curr_chan] = map_ch; // do not populate and skip the missing N163 channels! map_ch++; - } + }*/ } if (expansions & 4) { + ds.systemChans[systemID]=1; ds.system[systemID++] = DIV_SYSTEM_FDS; map_channels[curr_chan] = map_ch; @@ -730,6 +735,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si map_ch++; } if (expansions & 2) { + ds.systemChans[systemID]=6; ds.system[systemID++] = DIV_SYSTEM_VRC7; for (int ch = 0; ch < 6; ch++) { @@ -741,6 +747,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si } if (expansions & 32) { ds.system[systemID] = DIV_SYSTEM_AY8910; + ds.systemChans[systemID]=3; ds.systemFlags[systemID++].set("chipType", 2); // Sunsoft 5B for (int ch = 0; ch < 3; ch++) { @@ -751,6 +758,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si } } if (expansions & 64) { + ds.systemChans[systemID]=3; ds.system[systemID++] = DIV_SYSTEM_AY8930; for (int ch = 0; ch < 3; ch++) { @@ -761,6 +769,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si } } if (expansions & 128) { + ds.systemChans[systemID]=6; ds.system[systemID++] = DIV_SYSTEM_SAA1099; for (int ch = 0; ch < 6; ch++) { @@ -770,6 +779,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si } } if (expansions & 256) { + ds.systemChans[systemID]=5; ds.system[systemID++] = DIV_SYSTEM_5E01; for (int ch = 0; ch < 5; ch++) { @@ -779,6 +789,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si } } if (expansions & 512) { + ds.systemChans[systemID]=3; ds.system[systemID++] = DIV_SYSTEM_C64_6581; for (int ch = 0; ch < 3; ch++) { @@ -788,6 +799,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si } } if (expansions & 1024) { + ds.systemChans[systemID]=3; ds.system[systemID++] = DIV_SYSTEM_C64_8580; for (int ch = 0; ch < 3; ch++) { @@ -797,6 +809,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si } } if (expansions & 2048) { + ds.systemChans[systemID]=4; ds.system[systemID++] = DIV_SYSTEM_POKEY; for (int ch = 0; ch < 4; ch++) { @@ -817,13 +830,8 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si calcChans--; // no PCM channel for MMC5 in famitracker } - calcChans += getChannelCount(ds.system[i]); - total_chans += getChannelCount(ds.system[i]); - - if (ds.system[i] == DIV_SYSTEM_N163) { - calcChans -= getChannelCount(ds.system[i]); - calcChans += (int)n163Chans; - } + calcChans += ds.systemChans[i]; + total_chans += ds.systemChans[i]; } if (calcChans != tchans) { // TODO: would ignore trigger CVE? too bad if so! @@ -2802,7 +2810,6 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si } } - ds.initDefaultSystemChans(); ds.recalcChans(); if (active) quitDispatch(); diff --git a/src/engine/song.h b/src/engine/song.h index e0bde3f10..d34f7bc9d 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -392,14 +392,24 @@ struct DivSong { std::vector effects; - // INTERNAL STATE - do not modify. + /** + * INTERNAL STATE - do not modify. + */ + // default/"null" instruments (when instrument is none/-1) DivInstrument nullIns, nullInsOPLL, nullInsOPL, nullInsOPLDrums, nullInsQSound, nullInsESFM; + // default assets, returned by getWave()/getSample() in DivEngine DivWavetable nullWave; DivSample nullSample; + // channel information arrays. + // chip of a channel DivSystem sysOfChan[DIV_MAX_CHANS]; + // dispatch (chip index) of a channel int dispatchOfChan[DIV_MAX_CHANS]; + // tracker channel to chip channel mapping + // -1 means "nowhere". int dispatchChanOfChan[DIV_MAX_CHANS]; + // the first channel of a chip, indexed per channel int dispatchFirstChan[DIV_MAX_CHANS]; std::vector possibleInsTypes; diff --git a/src/gui/gui.h b/src/gui/gui.h index ec2cb5766..4a2d96e9a 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -3083,7 +3083,7 @@ class FurnaceGUI { void drawRefPlayer(); void drawMultiInsSetup(); - float drawSystemChannelInfo(const DivSysDef* whichDef, int keyHitOffset=-1, float width=-1.0f); + float drawSystemChannelInfo(const DivSysDef* whichDef, int keyHitOffset=-1, float width=-1.0f, int chanCount=-1); void drawSystemChannelInfoText(const DivSysDef* whichDef); void drawVolMeterInternal(ImDrawList* dl, ImRect rect, float* data, int chans, bool aspectRatio); diff --git a/src/gui/sysManager.cpp b/src/gui/sysManager.cpp index 4ebb1f888..28d7b0c7a 100644 --- a/src/gui/sysManager.cpp +++ b/src/gui/sysManager.cpp @@ -145,7 +145,7 @@ void FurnaceGUI::drawSysManager() { // channel LEDs and chip config button float height=0; if (settings.rackShowLEDs) { - height=drawSystemChannelInfo(sysDef,dispatchOff,ImGui::GetContentRegionAvail().x-(ImGui::CalcTextSize(ICON_FA_CHEVRON_DOWN).x+ImGui::GetStyle().ItemSpacing.x)); + height=drawSystemChannelInfo(sysDef,dispatchOff,ImGui::GetContentRegionAvail().x-(ImGui::CalcTextSize(ICON_FA_CHEVRON_DOWN).x+ImGui::GetStyle().ItemSpacing.x),e->song.systemChans[i]); } ImGuiID openedID=ImGui::GetID("OpenSysConfig"); @@ -168,7 +168,7 @@ void FurnaceGUI::drawSysManager() { ImGui::EndChild(); ImGui::PopID(); - dispatchOff+=sysDef->channels; + dispatchOff+=e->song.systemChans[i]; } if (e->song.systemLenchannels; + ImDrawList* dl=ImGui::GetWindowDrawList(); const ImVec2 p=ImGui::GetCursorScreenPos(); if (tooltipWidth<=0.0f) tooltipWidth=ImGui::GetContentRegionAvail().x; ImVec2 sep=ImGui::GetStyle().ItemSpacing; sep.x*=0.5f; ImVec2 ledSize=ImVec2( - (tooltipWidth-sep.x*(whichDef->channels-1))/(float)whichDef->channels, + (tooltipWidth-sep.x*(chanCount-1))/(float)chanCount, settings.iconSize*dpiScale ); if (ledSize.x<8.0f*dpiScale) ledSize.x=8.0f*dpiScale; float x=p.x, y=p.y; - for (int i=0; ichannels; i++) { + for (int i=0; itooltipWidth+p.x) { x=p.x; y+=ledSize.y+sep.y; } - ImVec4 color=uiColors[whichDef->chanTypes[i]+GUI_COLOR_CHANNEL_FM]; + ImVec4 color=uiColors[GUI_COLOR_CHANNEL_BG]; + if (ichannels) color=uiColors[whichDef->chanTypes[i]+GUI_COLOR_CHANNEL_FM]; if (keyHitOffset>=0) { if (e->isChannelMuted(keyHitOffset+i)) { color=uiColors[GUI_COLOR_CHANNEL_MUTED];