From 7f0074511c3f98c05930d12fe6a190a6949be36c Mon Sep 17 00:00:00 2001 From: Laurens Holst Date: Sun, 1 May 2022 19:57:44 +0200 Subject: [PATCH] Move renderSamples() to DivDispatch implementations. To prevent rendering samples for systems that are not in use. Additionally, it gives the systems more flexibility to render the samples according to their specific configuration. --- src/engine/dispatch.h | 20 ++++ src/engine/engine.cpp | 122 +++--------------------- src/engine/engine.h | 28 +----- src/engine/fileOps.cpp | 18 ++-- src/engine/platform/abstract.cpp | 16 ++++ src/engine/platform/qsound.cpp | 54 ++++++++++- src/engine/platform/qsound.h | 6 ++ src/engine/platform/x1_010.cpp | 48 +++++++++- src/engine/platform/x1_010.h | 14 ++- src/engine/platform/ym2610.cpp | 85 ++++++++++++++++- src/engine/platform/ym2610.h | 25 ++++- src/engine/platform/ym2610Interface.cpp | 10 +- src/engine/platform/ym2610b.cpp | 5 +- src/engine/platform/ym2610b.h | 3 +- src/engine/vgmOps.cpp | 65 +++++++------ src/gui/stats.cpp | 27 +++--- 16 files changed, 327 insertions(+), 219 deletions(-) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 7e5f998b..58c9c9b7 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -438,6 +438,26 @@ class DivDispatch { */ virtual const char** getRegisterSheet(); + /** + * Get sample memory buffer. + */ + virtual const void* getSampleMem(int index = 0); + + /** + * Get sample memory capacity. + */ + virtual size_t getSampleMemCapacity(int index = 0); + + /** + * Get sample memory usage. + */ + virtual size_t getSampleMemUsage(int index = 0); + + /** + * Render samples into sample memory. + */ + virtual void renderSamples(); + /** * initialize this DivDispatch. * @param parent the parent DivEngine. diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 3a0a841d..279d7522 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -506,118 +506,12 @@ void DivEngine::renderSamples() { song.sample[i]->render(); } - // step 2: allocate ADPCM-A samples - if (adpcmAMem==NULL) adpcmAMem=new unsigned char[16777216]; - - size_t memPos=0; - for (int i=0; ilengthA+255)&(~0xff); - if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) { - memPos=(memPos+0xfffff)&0xf00000; + // step 2: render samples to dispatch + for (int i=0; irenderSamples(); } - if (memPos>=16777216) { - logW("out of ADPCM-A memory for sample %d!",i); - break; - } - if (memPos+paddedLen>=16777216) { - memcpy(adpcmAMem+memPos,s->dataA,16777216-memPos); - logW("out of ADPCM-A memory for sample %d!",i); - } else { - memcpy(adpcmAMem+memPos,s->dataA,paddedLen); - } - s->offA=memPos; - memPos+=paddedLen; } - adpcmAMemLen=memPos+256; - - // step 2: allocate ADPCM-B samples - if (adpcmBMem==NULL) adpcmBMem=new unsigned char[16777216]; - - memPos=0; - for (int i=0; ilengthB+255)&(~0xff); - if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) { - memPos=(memPos+0xfffff)&0xf00000; - } - if (memPos>=16777216) { - logW("out of ADPCM-B memory for sample %d!",i); - break; - } - if (memPos+paddedLen>=16777216) { - memcpy(adpcmBMem+memPos,s->dataB,16777216-memPos); - logW("out of ADPCM-B memory for sample %d!",i); - } else { - memcpy(adpcmBMem+memPos,s->dataB,paddedLen); - } - s->offB=memPos; - memPos+=paddedLen; - } - adpcmBMemLen=memPos+256; - - // step 4: allocate qsound pcm samples - if (qsoundMem==NULL) qsoundMem=new unsigned char[16777216]; - memset(qsoundMem,0,16777216); - - memPos=0; - for (int i=0; ilength8; - if (length>65536-16) { - length=65536-16; - } - if ((memPos&0xff0000)!=((memPos+length)&0xff0000)) { - memPos=(memPos+0xffff)&0xff0000; - } - if (memPos>=16777216) { - logW("out of QSound PCM memory for sample %d!",i); - break; - } - if (memPos+length>=16777216) { - for (unsigned int i=0; i<16777216-(memPos+length); i++) { - qsoundMem[(memPos+i)^0x8000]=s->data8[i]; - } - logW("out of QSound PCM memory for sample %d!",i); - } else { - for (int i=0; idata8[i]; - } - } - s->offQSound=memPos^0x8000; - memPos+=length+16; - } - qsoundMemLen=memPos+256; - - // step 4: allocate x1-010 pcm samples - if (x1_010Mem==NULL) x1_010Mem=new unsigned char[1048576]; - memset(x1_010Mem,0,1048576); - - memPos=0; - for (int i=0; ilength8+4095)&(~0xfff); - // fit sample bank size to 128KB for Seta 2 external bankswitching logic (not emulated yet!) - if (paddedLen>131072) { - paddedLen=131072; - } - if ((memPos&0xfe0000)!=((memPos+paddedLen)&0xfe0000)) { - memPos=(memPos+0x1ffff)&0xfe0000; - } - if (memPos>=1048576) { - logW("out of X1-010 memory for sample %d!",i); - break; - } - if (memPos+paddedLen>=1048576) { - memcpy(x1_010Mem+memPos,s->data8,1048576-memPos); - logW("out of X1-010 memory for sample %d!",i); - } else { - memcpy(x1_010Mem+memPos,s->data8,paddedLen); - } - s->offX1_010=memPos; - memPos+=paddedLen; - } - x1_010MemLen=memPos+256; } String DivEngine::encodeSysDesc(std::vector& desc) { @@ -725,11 +619,11 @@ void DivEngine::createNew(const int* description) { initSongWithDesc(description); } recalcChans(); - renderSamples(); saveLock.unlock(); BUSY_END; initDispatch(); BUSY_BEGIN; + renderSamples(); reset(); BUSY_END; } @@ -967,6 +861,11 @@ DivSample* DivEngine::getSample(int index) { return song.sample[index]; } +DivDispatch* DivEngine::getDispatch(int index) { + if (index<0 || index>=song.systemLen) return NULL; + return disCont[index].dispatch; +} + void DivEngine::setLoops(int loops) { remainingLoops=loops; } @@ -2812,6 +2711,7 @@ bool DivEngine::init() { oscBuf[1]=new float[32768]; initDispatch(); + renderSamples(); reset(); active=true; diff --git a/src/engine/engine.h b/src/engine/engine.h index 2ca301c5..dc1436ee 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -422,6 +422,7 @@ class DivEngine { DivInstrument* getIns(int index, DivInstrumentType fallbackType=DIV_INS_FM); DivWavetable* getWave(int index); DivSample* getSample(int index); + DivDispatch* getDispatch(int index); // parse system setup description String encodeSysDesc(std::vector& desc); std::vector decodeSysDesc(String desc); @@ -849,19 +850,6 @@ class DivEngine { // terminate the engine. bool quit(); - unsigned char* adpcmAMem; - size_t adpcmAMemLen; - unsigned char* adpcmBMem; - size_t adpcmBMemLen; - unsigned char* qsoundMem; - size_t qsoundMemLen; - unsigned char* qsoundAMem; - size_t qsoundAMemLen; - unsigned char* dpcmMem; - size_t dpcmMemLen; - unsigned char* x1_010Mem; - size_t x1_010MemLen; - DivEngine(): output(NULL), exportThread(NULL), @@ -935,19 +923,7 @@ class DivEngine { oscSize(1), oscReadPos(0), oscWritePos(0), - tickMult(1), - adpcmAMem(NULL), - adpcmAMemLen(0), - adpcmBMem(NULL), - adpcmBMemLen(0), - qsoundMem(NULL), - qsoundMemLen(0), - qsoundAMem(NULL), - qsoundAMemLen(0), - dpcmMem(NULL), - dpcmMemLen(0), - x1_010Mem(NULL), - x1_010MemLen(0) { + tickMult(1) { memset(isMuted,0,DIV_MAX_CHANS*sizeof(bool)); memset(keyHit,0,DIV_MAX_CHANS*sizeof(bool)); memset(dispatchChanOfChan,0,DIV_MAX_CHANS*sizeof(int)); diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index cfd23e1f..b543e3e1 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -899,12 +899,14 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { song.unload(); song=ds; recalcChans(); - renderSamples(); saveLock.unlock(); BUSY_END; if (active) { initDispatch(); - syncReset(); + BUSY_BEGIN; + renderSamples(); + reset(); + BUSY_END; } } catch (EndOfFileException& e) { logE("premature end of file!"); @@ -1596,12 +1598,14 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { song.unload(); song=ds; recalcChans(); - renderSamples(); saveLock.unlock(); BUSY_END; if (active) { initDispatch(); - syncReset(); + BUSY_BEGIN; + renderSamples(); + reset(); + BUSY_END; } } catch (EndOfFileException& e) { logE("premature end of file!"); @@ -2005,12 +2009,14 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) { song.unload(); song=ds; recalcChans(); - renderSamples(); saveLock.unlock(); BUSY_END; if (active) { initDispatch(); - syncReset(); + BUSY_BEGIN; + renderSamples(); + reset(); + BUSY_END; } success=true; } catch (EndOfFileException& e) { diff --git a/src/engine/platform/abstract.cpp b/src/engine/platform/abstract.cpp index 91f61fc6..54366e1b 100644 --- a/src/engine/platform/abstract.cpp +++ b/src/engine/platform/abstract.cpp @@ -141,6 +141,22 @@ const char** DivDispatch::getRegisterSheet() { return NULL; } +const void* DivDispatch::getSampleMem(int index) { + return NULL; +} + +size_t DivDispatch::getSampleMemCapacity(int index) { + return 0; +} + +size_t DivDispatch::getSampleMemUsage(int index) { + return 0; +} + +void DivDispatch::renderSamples() { + +} + int DivDispatch::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { return 0; } diff --git a/src/engine/platform/qsound.cpp b/src/engine/platform/qsound.cpp index c5d003be..6e89e5b6 100644 --- a/src/engine/platform/qsound.cpp +++ b/src/engine/platform/qsound.cpp @@ -268,8 +268,6 @@ const char* DivPlatformQSound::getEffectName(unsigned char effect) { return NULL; } void DivPlatformQSound::acquire(short* bufL, short* bufR, size_t start, size_t len) { - chip.rom_data = parent->qsoundMem; - chip.rom_mask = 0xffffff; for (size_t h=start; hsong.sampleLen; i++) { + DivSample* s=parent->song.sample[i]; + int length=s->length8; + if (length>65536-16) { + length=65536-16; + } + if ((memPos&0xff0000)!=((memPos+length)&0xff0000)) { + memPos=(memPos+0xffff)&0xff0000; + } + if (memPos>=getSampleMemCapacity()) { + logW("out of QSound PCM memory for sample %d!",i); + break; + } + if (memPos+length>=getSampleMemCapacity()) { + for (unsigned int i=0; idata8[i]; + } + logW("out of QSound PCM memory for sample %d!",i); + } else { + for (int i=0; idata8[i]; + } + } + s->offQSound=memPos^0x8000; + memPos+=length+16; + } + sampleMemLen=memPos+256; +} + int DivPlatformQSound::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { parent=p; dumpWrites=false; @@ -651,8 +694,10 @@ int DivPlatformQSound::init(DivEngine* p, int channels, int sugRate, unsigned in chipClock=60000000; rate = qsound_start(&chip, chipClock); - chip.rom_data = (unsigned char*)&chip.rom_mask; - chip.rom_mask = 0; + sampleMem=new unsigned char[getSampleMemCapacity()]; + sampleMemLen=0; + chip.rom_data=sampleMem; + chip.rom_mask=0xffffff; reset(); for (int i=0; i<19; i++) { @@ -662,6 +707,7 @@ int DivPlatformQSound::init(DivEngine* p, int channels, int sugRate, unsigned in } void DivPlatformQSound::quit() { + delete[] sampleMem; for (int i=0; i<19; i++) { delete oscBuf[i]; } diff --git a/src/engine/platform/qsound.h b/src/engine/platform/qsound.h index 0fbce3b3..d12e952e 100644 --- a/src/engine/platform/qsound.h +++ b/src/engine/platform/qsound.h @@ -67,6 +67,8 @@ class DivPlatformQSound: public DivDispatch { int echoDelay; int echoFeedback; + unsigned char* sampleMem; + size_t sampleMemLen; struct qsound_chip chip; unsigned short regPool[512]; @@ -94,6 +96,10 @@ class DivPlatformQSound: public DivDispatch { void poke(std::vector& wlist); const char** getRegisterSheet(); const char* getEffectName(unsigned char effect); + const void* getSampleMem(int index = 0); + size_t getSampleMemCapacity(int index = 0); + size_t getSampleMemUsage(int index = 0); + void renderSamples(); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); }; diff --git a/src/engine/platform/x1_010.cpp b/src/engine/platform/x1_010.cpp index a2e28b51..03cd4f6b 100644 --- a/src/engine/platform/x1_010.cpp +++ b/src/engine/platform/x1_010.cpp @@ -19,6 +19,7 @@ #include "x1_010.h" #include "../engine.h" +#include "../../ta-log.h" #include //#define rWrite(a,v) pendingWrites[a]=v; @@ -909,6 +910,48 @@ void DivPlatformX1_010::poke(std::vector& wlist) { for (DivRegWrite& i: wlist) rWrite(i.addr,i.val); } +const void* DivPlatformX1_010::getSampleMem(int index) { + return index == 0 ? sampleMem : 0; +} + +size_t DivPlatformX1_010::getSampleMemCapacity(int index) { + return index == 0 ? 1048576 : 0; +} + +size_t DivPlatformX1_010::getSampleMemUsage(int index) { + return index == 0 ? sampleMemLen : 0; +} + +void DivPlatformX1_010::renderSamples() { + memset(sampleMem,0,getSampleMemCapacity()); + + size_t memPos=0; + for (int i=0; isong.sampleLen; i++) { + DivSample* s=parent->song.sample[i]; + int paddedLen=(s->length8+4095)&(~0xfff); + // fit sample bank size to 128KB for Seta 2 external bankswitching logic (not emulated yet!) + if (paddedLen>131072) { + paddedLen=131072; + } + if ((memPos&0xfe0000)!=((memPos+paddedLen)&0xfe0000)) { + memPos=(memPos+0x1ffff)&0xfe0000; + } + if (memPos>=getSampleMemCapacity()) { + logW("out of X1-010 memory for sample %d!",i); + break; + } + if (memPos+paddedLen>=getSampleMemCapacity()) { + memcpy(sampleMem+memPos,s->data8,getSampleMemCapacity()-memPos); + logW("out of X1-010 memory for sample %d!",i); + } else { + memcpy(sampleMem+memPos,s->data8,paddedLen); + } + s->offX1_010=memPos; + memPos+=paddedLen; + } + sampleMemLen=memPos+256; +} + int DivPlatformX1_010::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { parent=p; dumpWrites=false; @@ -919,7 +962,9 @@ int DivPlatformX1_010::init(DivEngine* p, int channels, int sugRate, unsigned in oscBuf[i]=new DivDispatchOscBuffer; } setFlags(flags); - intf.parent=parent; + sampleMem=new unsigned char[getSampleMemCapacity()]; + sampleMemLen=0; + intf.memory=sampleMem; x1_010=new x1_010_core(intf); x1_010->reset(); reset(); @@ -931,6 +976,7 @@ void DivPlatformX1_010::quit() { delete oscBuf[i]; } delete x1_010; + delete[] sampleMem; } DivPlatformX1_010::~DivPlatformX1_010() { diff --git a/src/engine/platform/x1_010.h b/src/engine/platform/x1_010.h index 11de4bf4..939280ef 100644 --- a/src/engine/platform/x1_010.h +++ b/src/engine/platform/x1_010.h @@ -28,13 +28,13 @@ class DivX1_010Interface: public x1_010_mem_intf { public: - DivEngine* parent; + unsigned char* memory; int sampleBank; virtual u8 read_byte(u32 address) override { - if (parent->x1_010Mem==NULL) return 0; - return parent->x1_010Mem[address & 0xfffff]; + if (memory==NULL) return 0; + return memory[address & 0xfffff]; } - DivX1_010Interface(): parent(NULL), sampleBank(0) {} + DivX1_010Interface(): memory(NULL), sampleBank(0) {} }; class DivPlatformX1_010: public DivDispatch { @@ -115,6 +115,8 @@ class DivPlatformX1_010: public DivDispatch { DivDispatchOscBuffer* oscBuf[16]; bool isMuted[16]; bool stereo=false; + unsigned char* sampleMem; + size_t sampleMemLen; unsigned char sampleBank; DivX1_010Interface intf; x1_010_core* x1_010; @@ -141,6 +143,10 @@ class DivPlatformX1_010: public DivDispatch { void notifyInsDeletion(void* ins); void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); + const void* getSampleMem(int index = 0); + size_t getSampleMemCapacity(int index = 0); + size_t getSampleMemUsage(int index = 0); + void renderSamples(); const char** getRegisterSheet(); const char* getEffectName(unsigned char effect); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 5154acc6..3711515a 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -20,6 +20,7 @@ #include "ym2610.h" #include "sound/ymfm/ymfm.h" #include "../engine.h" +#include "../../ta-log.h" #include #include @@ -245,6 +246,85 @@ const char* regCheatSheetYM2610[]={ NULL }; +const void* DivPlatformYM2610Base::getSampleMem(int index) { + return index == 0 ? adpcmAMem : index == 1 ? adpcmBMem : NULL; +} + +size_t DivPlatformYM2610Base::getSampleMemCapacity(int index) { + return index == 0 ? 16777216 : index == 1 ? 16777216 : 0; +} + +size_t DivPlatformYM2610Base::getSampleMemUsage(int index) { + return index == 0 ? adpcmAMemLen : index == 1 ? adpcmBMemLen : 0; +} + +void DivPlatformYM2610Base::renderSamples() { + memset(adpcmAMem,0,getSampleMemCapacity(0)); + + size_t memPos=0; + for (int i=0; isong.sampleLen; i++) { + DivSample* s=parent->song.sample[i]; + int paddedLen=(s->lengthA+255)&(~0xff); + if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) { + memPos=(memPos+0xfffff)&0xf00000; + } + if (memPos>=getSampleMemCapacity(0)) { + logW("out of ADPCM-A memory for sample %d!",i); + break; + } + if (memPos+paddedLen>=getSampleMemCapacity(0)) { + memcpy(adpcmAMem+memPos,s->dataA,getSampleMemCapacity(0)-memPos); + logW("out of ADPCM-A memory for sample %d!",i); + } else { + memcpy(adpcmAMem+memPos,s->dataA,paddedLen); + } + s->offA=memPos; + memPos+=paddedLen; + } + adpcmAMemLen=memPos+256; + + memset(adpcmBMem,0,getSampleMemCapacity(1)); + + memPos=0; + for (int i=0; isong.sampleLen; i++) { + DivSample* s=parent->song.sample[i]; + int paddedLen=(s->lengthB+255)&(~0xff); + if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) { + memPos=(memPos+0xfffff)&0xf00000; + } + if (memPos>=getSampleMemCapacity(1)) { + logW("out of ADPCM-B memory for sample %d!",i); + break; + } + if (memPos+paddedLen>=getSampleMemCapacity(1)) { + memcpy(adpcmBMem+memPos,s->dataB,getSampleMemCapacity(1)-memPos); + logW("out of ADPCM-B memory for sample %d!",i); + } else { + memcpy(adpcmBMem+memPos,s->dataB,paddedLen); + } + s->offB=memPos; + memPos+=paddedLen; + } + adpcmBMemLen=memPos+256; +} + +int DivPlatformYM2610Base::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { + parent=p; + adpcmAMem=new unsigned char[getSampleMemCapacity(0)]; + adpcmAMemLen=0; + adpcmBMem=new unsigned char[getSampleMemCapacity(1)]; + adpcmBMemLen=0; + iface.adpcmAMem=adpcmAMem; + iface.adpcmBMem=adpcmBMem; + iface.sampleBank=0; + return 0; +} + +void DivPlatformYM2610Base::quit() { + delete[] adpcmAMem; + delete[] adpcmBMem; +} + const char** DivPlatformYM2610::getRegisterSheet() { return regCheatSheetYM2610; } @@ -1185,7 +1265,7 @@ void DivPlatformYM2610::setSkipRegisterWrites(bool value) { } int DivPlatformYM2610::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { - parent=p; + DivPlatformYM2610Base::init(p, channels, sugRate, flags); dumpWrites=false; skipRegisterWrites=false; for (int i=0; i<14; i++) { @@ -1197,8 +1277,6 @@ int DivPlatformYM2610::init(DivEngine* p, int channels, int sugRate, unsigned in for (int i=0; i<14; i++) { oscBuf[i]->rate=rate; } - iface.parent=parent; - iface.sampleBank=0; fm=new ymfm::ym2610(iface); // YM2149, 2MHz ay=new DivPlatformAY8910; @@ -1215,6 +1293,7 @@ void DivPlatformYM2610::quit() { ay->quit(); delete ay; delete fm; + DivPlatformYM2610Base::quit(); } DivPlatformYM2610::~DivPlatformYM2610() { diff --git a/src/engine/platform/ym2610.h b/src/engine/platform/ym2610.h index c46bc3c4..45ecb335 100644 --- a/src/engine/platform/ym2610.h +++ b/src/engine/platform/ym2610.h @@ -27,14 +27,32 @@ class DivYM2610Interface: public ymfm::ymfm_interface { public: - DivEngine* parent; + unsigned char* adpcmAMem; + unsigned char* adpcmBMem; int sampleBank; uint8_t ymfm_external_read(ymfm::access_class type, uint32_t address); void ymfm_external_write(ymfm::access_class type, uint32_t address, uint8_t data); - DivYM2610Interface(): parent(NULL), sampleBank(0) {} + DivYM2610Interface(): adpcmAMem(NULL), adpcmBMem(NULL), sampleBank(0) {} }; -class DivPlatformYM2610: public DivDispatch { +class DivPlatformYM2610Base: public DivDispatch { + protected: + unsigned char* adpcmAMem; + size_t adpcmAMemLen; + unsigned char* adpcmBMem; + size_t adpcmBMemLen; + DivYM2610Interface iface; + + public: + const void* getSampleMem(int index); + size_t getSampleMemCapacity(int index); + size_t getSampleMemUsage(int index); + void renderSamples(); + int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); + void quit(); +}; + +class DivPlatformYM2610: public DivPlatformYM2610Base { protected: const unsigned short chanOffs[4]={ 0x01, 0x02, 0x101, 0x102 @@ -93,7 +111,6 @@ class DivPlatformYM2610: public DivDispatch { std::queue writes; ymfm::ym2610* fm; ymfm::ym2610::output_data fmout; - DivYM2610Interface iface; DivPlatformAY8910* ay; unsigned char regPool[512]; diff --git a/src/engine/platform/ym2610Interface.cpp b/src/engine/platform/ym2610Interface.cpp index 9154b40e..d442ce34 100644 --- a/src/engine/platform/ym2610Interface.cpp +++ b/src/engine/platform/ym2610Interface.cpp @@ -24,13 +24,11 @@ uint8_t DivYM2610Interface::ymfm_external_read(ymfm::access_class type, uint32_t address) { switch (type) { case ymfm::ACCESS_ADPCM_A: - if (parent->adpcmAMem==NULL) return 0; - if ((address&0xffffff)>=parent->adpcmAMemLen) return 0; - return parent->adpcmAMem[address&0xffffff]; + if (adpcmAMem==NULL) return 0; + return adpcmAMem[address&0xffffff]; case ymfm::ACCESS_ADPCM_B: - if (parent->adpcmBMem==NULL) return 0; - if ((address&0xffffff)>=parent->adpcmBMemLen) return 0; - return parent->adpcmBMem[address&0xffffff]; + if (adpcmBMem==NULL) return 0; + return adpcmBMem[address&0xffffff]; default: return 0; } diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index a0f1a6e3..9c126c2b 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -1243,7 +1243,7 @@ void DivPlatformYM2610B::setSkipRegisterWrites(bool value) { } int DivPlatformYM2610B::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { - parent=p; + DivPlatformYM2610Base::init(p, channels, sugRate, flags); dumpWrites=false; skipRegisterWrites=false; for (int i=0; i<16; i++) { @@ -1255,8 +1255,6 @@ int DivPlatformYM2610B::init(DivEngine* p, int channels, int sugRate, unsigned i for (int i=0; i<16; i++) { oscBuf[i]->rate=rate; } - iface.parent=parent; - iface.sampleBank=0; fm=new ymfm::ym2610b(iface); // YM2149, 2MHz ay=new DivPlatformAY8910; @@ -1273,6 +1271,7 @@ void DivPlatformYM2610B::quit() { ay->quit(); delete ay; delete fm; + DivPlatformYM2610Base::quit(); } DivPlatformYM2610B::~DivPlatformYM2610B() { diff --git a/src/engine/platform/ym2610b.h b/src/engine/platform/ym2610b.h index df0a8323..d1af3069 100644 --- a/src/engine/platform/ym2610b.h +++ b/src/engine/platform/ym2610b.h @@ -26,7 +26,7 @@ #include "ym2610.h" -class DivPlatformYM2610B: public DivDispatch { +class DivPlatformYM2610B: public DivPlatformYM2610Base { protected: const unsigned short chanOffs[6]={ 0x00, 0x01, 0x02, 0x100, 0x101, 0x102 @@ -85,7 +85,6 @@ class DivPlatformYM2610B: public DivDispatch { std::queue writes; ymfm::ym2610b* fm; ymfm::ym2610b::output_data fmout; - DivYM2610Interface iface; unsigned char regPool[512]; unsigned char lastBusy; diff --git a/src/engine/vgmOps.cpp b/src/engine/vgmOps.cpp index 7817c060..53800a52 100644 --- a/src/engine/vgmOps.cpp +++ b/src/engine/vgmOps.cpp @@ -713,10 +713,10 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) { bool writeDACSamples=false; bool writeNESSamples=false; bool writePCESamples=false; - int writeADPCM=0; + DivDispatch* writeADPCM[2]={NULL,NULL}; int writeSegaPCM=0; - int writeX1010=0; - int writeQSound=0; + DivDispatch* writeX1010[2]={NULL,NULL}; + DivDispatch* writeQSound[2]={NULL,NULL}; for (int i=0; ichipClock; willExport[i]=true; - writeX1010=1; + writeX1010[0]=disCont[i].dispatch; } else if (!(hasX1&0x40000000)) { isSecond[i]=true; willExport[i]=true; - writeX1010=2; + writeX1010[1]=disCont[i].dispatch; hasX1|=0x40000000; howManyChips++; } @@ -823,11 +823,11 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) { if (!hasOPNB) { hasOPNB=disCont[i].dispatch->chipClock; willExport[i]=true; - writeADPCM=1; + writeADPCM[0]=disCont[i].dispatch; } else if (!(hasOPNB&0x40000000)) { isSecond[i]=true; willExport[i]=true; - writeADPCM=2; + writeADPCM[1]=disCont[i].dispatch; hasOPNB|=0x40000000; howManyChips++; } @@ -929,11 +929,11 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) { // not be able to handle the 64kb sample bank trick hasQSound=disCont[i].dispatch->chipClock; willExport[i]=true; - writeQSound=1; + writeQSound[0]=disCont[i].dispatch; } else if (!(hasQSound&0x40000000)) { isSecond[i]=true; willExport[i]=false; - writeQSound=2; + writeQSound[1]=disCont[i].dispatch; addWarning("dual QSound is not supported by the VGM format"); } break; @@ -1249,56 +1249,55 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) { delete[] pcmMem; } - if (adpcmAMemLen>0) { - for (int i=0; igetSampleMemUsage(0)>0) { w->writeC(0x67); w->writeC(0x66); w->writeC(0x82); - w->writeI((adpcmAMemLen+8)|(i*0x80000000)); - w->writeI(adpcmAMemLen); + w->writeI((writeADPCM[i]->getSampleMemUsage(0)+8)|(i*0x80000000)); + w->writeI(writeADPCM[i]->getSampleMemCapacity(0)); w->writeI(0); - w->write(adpcmAMem,adpcmAMemLen); + w->write(writeADPCM[i]->getSampleMem(0),writeADPCM[i]->getSampleMemUsage(0)); } } - if (adpcmBMemLen>0) { - for (int i=0; igetSampleMemUsage(1)>0) { w->writeC(0x67); w->writeC(0x66); w->writeC(0x83); - w->writeI((adpcmBMemLen+8)|(i*0x80000000)); - w->writeI(adpcmBMemLen); + w->writeI((writeADPCM[i]->getSampleMemUsage(1)+8)|(i*0x80000000)); + w->writeI(writeADPCM[i]->getSampleMemCapacity(1)); w->writeI(0); - w->write(adpcmBMem,adpcmBMemLen); + w->write(writeADPCM[i]->getSampleMem(1),writeADPCM[i]->getSampleMemUsage(1)); } } - if (qsoundMemLen>0) { - // always write a whole bank - unsigned int blockSize=(qsoundMemLen+0xffff)&(~0xffff); - if (blockSize > 0x1000000) { - blockSize = 0x1000000; - } - for (int i=0; igetSampleMemUsage()>0) { + unsigned int blockSize=(writeQSound[i]->getSampleMemUsage()+0xffff)&(~0xffff); + if (blockSize > 0x1000000) { + blockSize = 0x1000000; + } w->writeC(0x67); w->writeC(0x66); w->writeC(0x8F); w->writeI((blockSize+8)|(i*0x80000000)); - w->writeI(0x1000000); + w->writeI(writeQSound[i]->getSampleMemCapacity()); w->writeI(0); - w->write(qsoundMem,blockSize); + w->write(writeQSound[i]->getSampleMem(),blockSize); } } - if (x1_010MemLen>0) { - for (int i=0; igetSampleMemUsage()>0) { w->writeC(0x67); w->writeC(0x66); w->writeC(0x91); - w->writeI((x1_010MemLen+8)|(i*0x80000000)); - w->writeI(x1_010MemLen); + w->writeI((writeX1010[i]->getSampleMemUsage()+8)|(i*0x80000000)); + w->writeI(writeX1010[i]->getSampleMemCapacity()); w->writeI(0); - w->write(x1_010Mem,x1_010MemLen); + w->write(writeX1010[i]->getSampleMem(),writeX1010[i]->getSampleMemUsage()); } } diff --git a/src/gui/stats.cpp b/src/gui/stats.cpp index 274be2ed..35d6cfc4 100644 --- a/src/gui/stats.cpp +++ b/src/gui/stats.cpp @@ -28,22 +28,17 @@ void FurnaceGUI::drawStats() { } if (!statsOpen) return; if (ImGui::Begin("Statistics",&statsOpen)) { - String adpcmAUsage=fmt::sprintf("%d/16384KB",e->adpcmAMemLen/1024); - String adpcmBUsage=fmt::sprintf("%d/16384KB",e->adpcmBMemLen/1024); - String qsoundUsage=fmt::sprintf("%d/16384KB",e->qsoundMemLen/1024); - String x1_010Usage=fmt::sprintf("%d/1024KB",e->x1_010MemLen/1024); - ImGui::Text("ADPCM-A"); - ImGui::SameLine(); - ImGui::ProgressBar(((float)e->adpcmAMemLen)/16777216.0f,ImVec2(-FLT_MIN,0),adpcmAUsage.c_str()); - ImGui::Text("ADPCM-B"); - ImGui::SameLine(); - ImGui::ProgressBar(((float)e->adpcmBMemLen)/16777216.0f,ImVec2(-FLT_MIN,0),adpcmBUsage.c_str()); - ImGui::Text("QSound"); - ImGui::SameLine(); - ImGui::ProgressBar(((float)e->qsoundMemLen)/16777216.0f,ImVec2(-FLT_MIN,0),qsoundUsage.c_str()); - ImGui::Text("X1-010"); - ImGui::SameLine(); - ImGui::ProgressBar(((float)e->x1_010MemLen)/1048576.0f,ImVec2(-FLT_MIN,0),x1_010Usage.c_str()); + for (int i=0; isong.systemLen; i++) { + DivDispatch* dispatch=e->getDispatch(i); + for (int j=0; dispatch!=NULL && dispatch->getSampleMemCapacity(j)>0; j++) { + size_t capacity=dispatch->getSampleMemCapacity(j); + size_t usage=dispatch->getSampleMemUsage(j); + String usageStr=fmt::sprintf("%d/%dKB",usage/1024,capacity/1024); + ImGui::Text("%s [%d]", e->getSystemName(e->song.system[i]), j); + ImGui::SameLine(); + ImGui::ProgressBar(((float)usage)/((float)capacity),ImVec2(-FLT_MIN,0),usageStr.c_str()); + } + } } if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_STATS; ImGui::End();