Merge branch 'master' of github.com:tildearrow/furnace

This commit is contained in:
tildearrow 2022-11-27 15:58:26 -05:00
commit 6750a8ef6a
30 changed files with 166 additions and 36 deletions

View file

@ -5,5 +5,4 @@
- (maybe) YM2612 CSM (no DualPCM) - (maybe) YM2612 CSM (no DualPCM)
- port presets to new format - port presets to new format
- bug fixes - bug fixes
- (maybe) ExtCh FM macros?
- (maybe) advanced linear arpeggio? (run arp+slide simultaneously) - (maybe) advanced linear arpeggio? (run arp+slide simultaneously)

View file

@ -532,6 +532,13 @@ class DivDispatch {
*/ */
virtual size_t getSampleMemCapacity(int index = 0); virtual size_t getSampleMemCapacity(int index = 0);
/**
* get sample memory name.
* @param index the memory index.
* @return a name, or NULL if it doesn't have any name in particular.
*/
virtual const char* getSampleMemName(int index=0);
/** /**
* Get sample memory usage. * Get sample memory usage.
* @param index the memory index. * @param index the memory index.
@ -550,8 +557,9 @@ class DivDispatch {
/** /**
* Render samples into sample memory. * Render samples into sample memory.
* @param sysID the chip's index in the chip list.
*/ */
virtual void renderSamples(); virtual void renderSamples(int sysID);
/** /**
* initialize this DivDispatch. * initialize this DivDispatch.

View file

@ -1315,7 +1315,7 @@ void DivEngine::renderSamples() {
// step 2: render samples to dispatch // step 2: render samples to dispatch
for (int i=0; i<song.systemLen; i++) { for (int i=0; i<song.systemLen; i++) {
if (disCont[i].dispatch!=NULL) { if (disCont[i].dispatch!=NULL) {
disCont[i].dispatch->renderSamples(); disCont[i].dispatch->renderSamples(i);
} }
} }
} }

View file

@ -152,15 +152,20 @@ size_t DivDispatch::getSampleMemCapacity(int index) {
return 0; return 0;
} }
const char* DivDispatch::getSampleMemName(int index) {
return NULL;
}
size_t DivDispatch::getSampleMemUsage(int index) { size_t DivDispatch::getSampleMemUsage(int index) {
return 0; return 0;
} }
bool DivDispatch::isSampleLoaded(int index, int sample) { bool DivDispatch::isSampleLoaded(int index, int sample) {
printf("you are calling.\n");
return false; return false;
} }
void DivDispatch::renderSamples() { void DivDispatch::renderSamples(int sysID) {
} }

View file

@ -368,8 +368,9 @@ bool DivPlatformMSM6258::isSampleLoaded(int index, int sample) {
return sampleLoaded[sample]; return sampleLoaded[sample];
} }
void DivPlatformMSM6258::renderSamples() { void DivPlatformMSM6258::renderSamples(int sysID) {
memset(adpcmMem,0,getSampleMemCapacity(0)); memset(adpcmMem,0,getSampleMemCapacity(0));
memset(sampleLoaded,0,256*sizeof(bool));
// sample data // sample data
size_t memPos=0; size_t memPos=0;
@ -377,6 +378,8 @@ void DivPlatformMSM6258::renderSamples() {
if (sampleCount>128) sampleCount=128; if (sampleCount>128) sampleCount=128;
for (int i=0; i<sampleCount; i++) { for (int i=0; i<sampleCount; i++) {
DivSample* s=parent->song.sample[i]; DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) continue;
int paddedLen=s->lengthVOX; int paddedLen=s->lengthVOX;
if (memPos>=getSampleMemCapacity(0)) { if (memPos>=getSampleMemCapacity(0)) {
logW("out of ADPCM memory for sample %d!",i); logW("out of ADPCM memory for sample %d!",i);
@ -387,6 +390,7 @@ void DivPlatformMSM6258::renderSamples() {
logW("out of ADPCM memory for sample %d!",i); logW("out of ADPCM memory for sample %d!",i);
} else { } else {
memcpy(adpcmMem+memPos,s->dataVOX,paddedLen); memcpy(adpcmMem+memPos,s->dataVOX,paddedLen);
sampleLoaded[i]=true;
} }
memPos+=paddedLen; memPos+=paddedLen;
} }

View file

@ -115,7 +115,7 @@ class DivPlatformMSM6258: public DivDispatch {
size_t getSampleMemCapacity(int index); size_t getSampleMemCapacity(int index);
size_t getSampleMemUsage(int index); size_t getSampleMemUsage(int index);
bool isSampleLoaded(int index, int sample); bool isSampleLoaded(int index, int sample);
void renderSamples(); void renderSamples(int chipID);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit(); void quit();

View file

@ -341,11 +341,12 @@ bool DivPlatformMSM6295::isSampleLoaded(int index, int sample) {
return sampleLoaded[sample]; return sampleLoaded[sample];
} }
void DivPlatformMSM6295::renderSamples() { void DivPlatformMSM6295::renderSamples(int sysID) {
unsigned int sampleOffVOX[256]; unsigned int sampleOffVOX[256];
memset(adpcmMem,0,getSampleMemCapacity(0)); memset(adpcmMem,0,getSampleMemCapacity(0));
memset(sampleOffVOX,0,256*sizeof(unsigned int)); memset(sampleOffVOX,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
// sample data // sample data
size_t memPos=128*8; size_t memPos=128*8;
@ -353,6 +354,11 @@ void DivPlatformMSM6295::renderSamples() {
if (sampleCount>128) sampleCount=128; if (sampleCount>128) sampleCount=128;
for (int i=0; i<sampleCount; i++) { for (int i=0; i<sampleCount; i++) {
DivSample* s=parent->song.sample[i]; DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOffVOX[i]=0;
continue;
}
int paddedLen=s->lengthVOX; int paddedLen=s->lengthVOX;
if (memPos>=getSampleMemCapacity(0)) { if (memPos>=getSampleMemCapacity(0)) {
logW("out of ADPCM memory for sample %d!",i); logW("out of ADPCM memory for sample %d!",i);
@ -363,6 +369,7 @@ void DivPlatformMSM6295::renderSamples() {
logW("out of ADPCM memory for sample %d!",i); logW("out of ADPCM memory for sample %d!",i);
} else { } else {
memcpy(adpcmMem+memPos,s->dataVOX,paddedLen); memcpy(adpcmMem+memPos,s->dataVOX,paddedLen);
sampleLoaded[i]=true;
} }
sampleOffVOX[i]=memPos; sampleOffVOX[i]=memPos;
memPos+=paddedLen; memPos+=paddedLen;

View file

@ -103,7 +103,7 @@ class DivPlatformMSM6295: public DivDispatch, public vgsound_emu_mem_intf {
virtual size_t getSampleMemCapacity(int index) override; virtual size_t getSampleMemCapacity(int index) override;
virtual size_t getSampleMemUsage(int index) override; virtual size_t getSampleMemUsage(int index) override;
virtual bool isSampleLoaded(int index, int sample) override; virtual bool isSampleLoaded(int index, int sample) override;
virtual void renderSamples() override; virtual void renderSamples(int chipID) override;
virtual int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags) override; virtual int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags) override;
virtual void quit() override; virtual void quit() override;

View file

@ -727,12 +727,18 @@ bool DivPlatformNES::isSampleLoaded(int index, int sample) {
return sampleLoaded[sample]; return sampleLoaded[sample];
} }
void DivPlatformNES::renderSamples() { void DivPlatformNES::renderSamples(int sysID) {
memset(dpcmMem,0,getSampleMemCapacity(0)); memset(dpcmMem,0,getSampleMemCapacity(0));\
memset(sampleLoaded,0,256*sizeof(bool));
size_t memPos=0; size_t memPos=0;
for (int i=0; i<parent->song.sampleLen; i++) { for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i]; DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOffDPCM[i]=0;
continue;
}
unsigned int paddedLen=(s->lengthDPCM+63)&(~0x3f); unsigned int paddedLen=(s->lengthDPCM+63)&(~0x3f);
logV("%d padded length: %d",i,paddedLen); logV("%d padded length: %d",i,paddedLen);
if ((memPos&(~0x3fff))!=((memPos+paddedLen)&(~0x3fff))) { if ((memPos&(~0x3fff))!=((memPos+paddedLen)&(~0x3fff))) {
@ -750,6 +756,7 @@ void DivPlatformNES::renderSamples() {
logW("out of DPCM memory for sample %d!",i); logW("out of DPCM memory for sample %d!",i);
} else { } else {
memcpy(dpcmMem+memPos,s->dataDPCM,MIN(s->lengthDPCM,paddedLen)); memcpy(dpcmMem+memPos,s->dataDPCM,MIN(s->lengthDPCM,paddedLen));
sampleLoaded[i]=true;
} }
sampleOffDPCM[i]=memPos; sampleOffDPCM[i]=memPos;
memPos+=paddedLen; memPos+=paddedLen;

View file

@ -117,7 +117,7 @@ class DivPlatformNES: public DivDispatch {
size_t getSampleMemCapacity(int index); size_t getSampleMemCapacity(int index);
size_t getSampleMemUsage(int index); size_t getSampleMemUsage(int index);
bool isSampleLoaded(int index, int sample); bool isSampleLoaded(int index, int sample);
void renderSamples(); void renderSamples(int chipID);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit(); void quit();
~DivPlatformNES(); ~DivPlatformNES();

View file

@ -1763,14 +1763,20 @@ bool DivPlatformOPL::isSampleLoaded(int index, int sample) {
return sampleLoaded[sample]; return sampleLoaded[sample];
} }
void DivPlatformOPL::renderSamples() { void DivPlatformOPL::renderSamples(int sysID) {
if (adpcmChan<0) return; if (adpcmChan<0) return;
memset(adpcmBMem,0,getSampleMemCapacity(0)); memset(adpcmBMem,0,getSampleMemCapacity(0));
memset(sampleOffB,0,256*sizeof(unsigned int)); memset(sampleOffB,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
size_t memPos=0; size_t memPos=0;
for (int i=0; i<parent->song.sampleLen; i++) { for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i]; DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOffB[i]=0;
continue;
}
int paddedLen=(s->lengthB+255)&(~0xff); int paddedLen=(s->lengthB+255)&(~0xff);
if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) { if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) {
memPos=(memPos+0xfffff)&0xf00000; memPos=(memPos+0xfffff)&0xf00000;
@ -1784,6 +1790,7 @@ void DivPlatformOPL::renderSamples() {
logW("out of ADPCM memory for sample %d!",i); logW("out of ADPCM memory for sample %d!",i);
} else { } else {
memcpy(adpcmBMem+memPos,s->dataB,paddedLen); memcpy(adpcmBMem+memPos,s->dataB,paddedLen);
sampleLoaded[i]=true;
} }
sampleOffB[i]=memPos; sampleOffB[i]=memPos;
memPos+=paddedLen; memPos+=paddedLen;

View file

@ -154,7 +154,7 @@ class DivPlatformOPL: public DivDispatch {
size_t getSampleMemCapacity(int index); size_t getSampleMemCapacity(int index);
size_t getSampleMemUsage(int index); size_t getSampleMemUsage(int index);
bool isSampleLoaded(int index, int sample); bool isSampleLoaded(int index, int sample);
void renderSamples(); void renderSamples(int chipID);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit(); void quit();
~DivPlatformOPL(); ~DivPlatformOPL();

View file

@ -651,12 +651,18 @@ bool DivPlatformQSound::isSampleLoaded(int index, int sample) {
} }
// TODO: ADPCM... come on... // TODO: ADPCM... come on...
void DivPlatformQSound::renderSamples() { void DivPlatformQSound::renderSamples(int sysID) {
memset(sampleMem,0,getSampleMemCapacity()); memset(sampleMem,0,getSampleMemCapacity());
memset(sampleLoaded,0,256*sizeof(bool));
size_t memPos=0; size_t memPos=0;
for (int i=0; i<parent->song.sampleLen; i++) { for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i]; DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
offPCM[i]=0;
continue;
}
int length=s->length8; int length=s->length8;
if (length>65536-16) { if (length>65536-16) {
length=65536-16; length=65536-16;
@ -677,6 +683,7 @@ void DivPlatformQSound::renderSamples() {
for (int i=0; i<length; i++) { for (int i=0; i<length; i++) {
sampleMem[(memPos+i)^0x8000]=s->data8[i]; sampleMem[(memPos+i)^0x8000]=s->data8[i];
} }
sampleLoaded[i]=true;
} }
offPCM[i]=memPos^0x8000; offPCM[i]=memPos^0x8000;
memPos+=length+16; memPos+=length+16;

View file

@ -105,7 +105,7 @@ class DivPlatformQSound: public DivDispatch {
size_t getSampleMemCapacity(int index = 0); size_t getSampleMemCapacity(int index = 0);
size_t getSampleMemUsage(int index = 0); size_t getSampleMemUsage(int index = 0);
bool isSampleLoaded(int index, int sample); bool isSampleLoaded(int index, int sample);
void renderSamples(); void renderSamples(int chipID);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit(); void quit();
}; };

View file

@ -391,13 +391,19 @@ bool DivPlatformRF5C68::isSampleLoaded(int index, int sample) {
return sampleLoaded[sample]; return sampleLoaded[sample];
} }
void DivPlatformRF5C68::renderSamples() { void DivPlatformRF5C68::renderSamples(int sysID) {
memset(sampleMem,0,getSampleMemCapacity()); memset(sampleMem,0,getSampleMemCapacity());
memset(sampleOffRFC,0,256*sizeof(unsigned int)); memset(sampleOffRFC,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
size_t memPos=0; size_t memPos=0;
for (int i=0; i<parent->song.sampleLen; i++) { for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i]; DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOffRFC[i]=0;
continue;
}
int length=s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT); int length=s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT);
int actualLength=MIN((int)(getSampleMemCapacity()-memPos)-31,length); int actualLength=MIN((int)(getSampleMemCapacity()-memPos)-31,length);
if (actualLength>0) { if (actualLength>0) {
@ -418,6 +424,7 @@ void DivPlatformRF5C68::renderSamples() {
} }
// align memPos to 256-byte boundary // align memPos to 256-byte boundary
memPos=(memPos+0xff)&~0xff; memPos=(memPos+0xff)&~0xff;
sampleLoaded[i]=true;
} }
sampleMemLen=memPos; sampleMemLen=memPos;
} }

View file

@ -101,7 +101,7 @@ class DivPlatformRF5C68: public DivDispatch {
size_t getSampleMemCapacity(int index = 0); size_t getSampleMemCapacity(int index = 0);
size_t getSampleMemUsage(int index = 0); size_t getSampleMemUsage(int index = 0);
bool isSampleLoaded(int index, int sample); bool isSampleLoaded(int index, int sample);
void renderSamples(); void renderSamples(int chipID);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit(); void quit();
private: private:

View file

@ -451,7 +451,7 @@ void DivPlatformSegaPCM::reset() {
} }
} }
void DivPlatformSegaPCM::renderSamples() { void DivPlatformSegaPCM::renderSamples(int sysID) {
size_t memPos=0; size_t memPos=0;
for (int i=0; i<parent->song.sampleLen; i++) { for (int i=0; i<parent->song.sampleLen; i++) {

View file

@ -110,7 +110,7 @@ class DivPlatformSegaPCM: public DivDispatch {
void tick(bool sysTick=true); void tick(bool sysTick=true);
void muteChannel(int ch, bool mute); void muteChannel(int ch, bool mute);
void notifyInsChange(int ins); void notifyInsChange(int ins);
void renderSamples(); void renderSamples(int chipID);
void setFlags(const DivConfig& flags); void setFlags(const DivConfig& flags);
bool isStereo(); bool isStereo();
void poke(unsigned int addr, unsigned short val); void poke(unsigned int addr, unsigned short val);

View file

@ -803,14 +803,20 @@ bool DivPlatformSNES::isSampleLoaded(int index, int sample) {
return sampleLoaded[sample]; return sampleLoaded[sample];
} }
void DivPlatformSNES::renderSamples() { void DivPlatformSNES::renderSamples(int sysID) {
memset(copyOfSampleMem,0,getSampleMemCapacity()); memset(copyOfSampleMem,0,getSampleMemCapacity());
memset(sampleOff,0,256*sizeof(unsigned int)); memset(sampleOff,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
// skip past sample table and wavetable buffer // skip past sample table and wavetable buffer
size_t memPos=sampleTableBase+8*4+8*9*16; size_t memPos=sampleTableBase+8*4+8*9*16;
for (int i=0; i<parent->song.sampleLen; i++) { for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i]; DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOff[i]=0;
continue;
}
int length=s->lengthBRR; int length=s->lengthBRR;
int actualLength=MIN((int)(getSampleMemCapacity()-memPos)/9*9,length); int actualLength=MIN((int)(getSampleMemCapacity()-memPos)/9*9,length);
if (actualLength>0) { if (actualLength>0) {
@ -828,6 +834,7 @@ void DivPlatformSNES::renderSamples() {
logW("out of BRR memory for sample %d!",i); logW("out of BRR memory for sample %d!",i);
break; break;
} }
sampleLoaded[i]=true;
} }
sampleMemLen=memPos; sampleMemLen=memPos;
memcpy(sampleMem,copyOfSampleMem,65536); memcpy(sampleMem,copyOfSampleMem,65536);

View file

@ -138,7 +138,7 @@ class DivPlatformSNES: public DivDispatch {
size_t getSampleMemCapacity(int index = 0); size_t getSampleMemCapacity(int index = 0);
size_t getSampleMemUsage(int index = 0); size_t getSampleMemUsage(int index = 0);
bool isSampleLoaded(int index, int sample); bool isSampleLoaded(int index, int sample);
void renderSamples(); void renderSamples(int chipID);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit(); void quit();
private: private:

View file

@ -524,7 +524,7 @@ void DivPlatformSoundUnit::setFlags(const DivConfig& flags) {
sampleMemSize=flags.getInt("sampleMemSize",0); sampleMemSize=flags.getInt("sampleMemSize",0);
su->Init(sampleMemSize?65536:8192,flags.getBool("pdm",false)); su->Init(sampleMemSize?65536:8192,flags.getBool("pdm",false));
renderSamples(); renderSamples(sysIDCache);
} }
void DivPlatformSoundUnit::poke(unsigned int addr, unsigned short val) { void DivPlatformSoundUnit::poke(unsigned int addr, unsigned short val) {
@ -553,14 +553,20 @@ bool DivPlatformSoundUnit::isSampleLoaded(int index, int sample) {
return sampleLoaded[sample]; return sampleLoaded[sample];
} }
void DivPlatformSoundUnit::renderSamples() { void DivPlatformSoundUnit::renderSamples(int sysID) {
memset(su->pcm,0,getSampleMemCapacity(0)); memset(su->pcm,0,getSampleMemCapacity(0));
memset(sampleOffSU,0,256*sizeof(unsigned int)); memset(sampleOffSU,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
size_t memPos=0; size_t memPos=0;
for (int i=0; i<parent->song.sampleLen; i++) { for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i]; DivSample* s=parent->song.sample[i];
if (s->data8==NULL) continue; if (s->data8==NULL) continue;
if (!s->renderOn[0][sysID]) {
sampleOffSU[i]=0;
continue;
}
int paddedLen=s->length8; int paddedLen=s->length8;
if (memPos>=getSampleMemCapacity(0)) { if (memPos>=getSampleMemCapacity(0)) {
logW("out of PCM memory for sample %d!",i); logW("out of PCM memory for sample %d!",i);
@ -571,12 +577,13 @@ void DivPlatformSoundUnit::renderSamples() {
logW("out of PCM memory for sample %d!",i); logW("out of PCM memory for sample %d!",i);
} else { } else {
memcpy(su->pcm+memPos,s->data8,paddedLen); memcpy(su->pcm+memPos,s->data8,paddedLen);
sampleLoaded[i]=true;
} }
sampleOffSU[i]=memPos; sampleOffSU[i]=memPos;
memPos+=paddedLen; memPos+=paddedLen;
} }
sampleMemLen=memPos; sampleMemLen=memPos;
sysIDCache=sysID;
} }
int DivPlatformSoundUnit::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) { int DivPlatformSoundUnit::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) {
@ -588,6 +595,7 @@ int DivPlatformSoundUnit::init(DivEngine* p, int channels, int sugRate, const Di
oscBuf[i]=new DivDispatchOscBuffer; oscBuf[i]=new DivDispatchOscBuffer;
} }
su=new SoundUnit(); su=new SoundUnit();
sysIDCache=0;
setFlags(flags); setFlags(flags);
reset(); reset();
return 8; return 8;

View file

@ -104,7 +104,7 @@ class DivPlatformSoundUnit: public DivDispatch {
unsigned int sampleOffSU[256]; unsigned int sampleOffSU[256];
bool sampleLoaded[256]; bool sampleLoaded[256];
int cycles, curChan, delay; int cycles, curChan, delay, sysIDCache;
short tempL; short tempL;
short tempR; short tempR;
unsigned char sampleBank, lfoMode, lfoSpeed; unsigned char sampleBank, lfoMode, lfoSpeed;
@ -140,7 +140,7 @@ class DivPlatformSoundUnit: public DivDispatch {
size_t getSampleMemCapacity(int index); size_t getSampleMemCapacity(int index);
size_t getSampleMemUsage(int index); size_t getSampleMemUsage(int index);
bool isSampleLoaded(int index, int sample); bool isSampleLoaded(int index, int sample);
void renderSamples(); void renderSamples(int chipID);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit(); void quit();
~DivPlatformSoundUnit(); ~DivPlatformSoundUnit();

View file

@ -955,13 +955,19 @@ bool DivPlatformX1_010::isSampleLoaded(int index, int sample) {
return sampleLoaded[sample]; return sampleLoaded[sample];
} }
void DivPlatformX1_010::renderSamples() { void DivPlatformX1_010::renderSamples(int sysID) {
memset(sampleMem,0,getSampleMemCapacity()); memset(sampleMem,0,getSampleMemCapacity());
memset(sampleOffX1,0,256*sizeof(unsigned int)); memset(sampleOffX1,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
size_t memPos=0; size_t memPos=0;
for (int i=0; i<parent->song.sampleLen; i++) { for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i]; DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOffX1[i]=0;
continue;
}
int paddedLen=(s->length8+4095)&(~0xfff); int paddedLen=(s->length8+4095)&(~0xfff);
if (isBanked) { if (isBanked) {
// fit sample bank size to 128KB for Seta 2 external bankswitching logic (not emulated yet!) // fit sample bank size to 128KB for Seta 2 external bankswitching logic (not emulated yet!)
@ -981,6 +987,7 @@ void DivPlatformX1_010::renderSamples() {
logW("out of X1-010 memory for sample %d!",i); logW("out of X1-010 memory for sample %d!",i);
} else { } else {
memcpy(sampleMem+memPos,s->data8,paddedLen); memcpy(sampleMem+memPos,s->data8,paddedLen);
sampleLoaded[i]=true;
} }
sampleOffX1[i]=memPos; sampleOffX1[i]=memPos;
memPos+=paddedLen; memPos+=paddedLen;

View file

@ -148,7 +148,7 @@ class DivPlatformX1_010: public DivDispatch, public vgsound_emu_mem_intf {
size_t getSampleMemCapacity(int index = 0); size_t getSampleMemCapacity(int index = 0);
size_t getSampleMemUsage(int index = 0); size_t getSampleMemUsage(int index = 0);
bool isSampleLoaded(int index, int sample); bool isSampleLoaded(int index, int sample);
void renderSamples(); void renderSamples(int chipID);
const char** getRegisterSheet(); const char** getRegisterSheet();
void setBanked(bool banked); void setBanked(bool banked);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);

View file

@ -1342,13 +1342,19 @@ bool DivPlatformYM2608::isSampleLoaded(int index, int sample) {
return sampleLoaded[sample]; return sampleLoaded[sample];
} }
void DivPlatformYM2608::renderSamples() { void DivPlatformYM2608::renderSamples(int sysID) {
memset(adpcmBMem,0,getSampleMemCapacity(0)); memset(adpcmBMem,0,getSampleMemCapacity(0));
memset(sampleOffB,0,256*sizeof(unsigned int)); memset(sampleOffB,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
size_t memPos=0; size_t memPos=0;
for (int i=0; i<parent->song.sampleLen; i++) { for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i]; DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOffB[i]=0;
continue;
}
int paddedLen=(s->lengthB+255)&(~0xff); int paddedLen=(s->lengthB+255)&(~0xff);
if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) { if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) {
memPos=(memPos+0xfffff)&0xf00000; memPos=(memPos+0xfffff)&0xf00000;
@ -1362,6 +1368,7 @@ void DivPlatformYM2608::renderSamples() {
logW("out of ADPCM memory for sample %d!",i); logW("out of ADPCM memory for sample %d!",i);
} else { } else {
memcpy(adpcmBMem+memPos,s->dataB,paddedLen); memcpy(adpcmBMem+memPos,s->dataB,paddedLen);
sampleLoaded[i]=true;
} }
sampleOffB[i]=memPos; sampleOffB[i]=memPos;
memPos+=paddedLen; memPos+=paddedLen;

View file

@ -139,7 +139,7 @@ class DivPlatformYM2608: public DivPlatformOPN {
size_t getSampleMemCapacity(int index); size_t getSampleMemCapacity(int index);
size_t getSampleMemUsage(int index); size_t getSampleMemUsage(int index);
bool isSampleLoaded(int index, int sample); bool isSampleLoaded(int index, int sample);
void renderSamples(); void renderSamples(int chipID);
void setFlags(const DivConfig& flags); void setFlags(const DivConfig& flags);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit(); void quit();

View file

@ -206,6 +206,10 @@ template<int ChanNum> class DivPlatformYM2610Base: public DivPlatformOPN {
return index == 0 ? 16777216 : index == 1 ? 16777216 : 0; return index == 0 ? 16777216 : index == 1 ? 16777216 : 0;
} }
const char* getSampleMemName(int index=0) {
return index == 0 ? "ADPCM-A" : index == 1 ? "ADPCM-B" : NULL;
}
size_t getSampleMemUsage(int index) { size_t getSampleMemUsage(int index) {
return index == 0 ? adpcmAMemLen : index == 1 ? adpcmBMemLen : 0; return index == 0 ? adpcmAMemLen : index == 1 ? adpcmBMemLen : 0;
} }
@ -216,7 +220,7 @@ template<int ChanNum> class DivPlatformYM2610Base: public DivPlatformOPN {
return sampleLoaded[index][sample]; return sampleLoaded[index][sample];
} }
void renderSamples() { void renderSamples(int sysID) {
memset(adpcmAMem,0,getSampleMemCapacity(0)); memset(adpcmAMem,0,getSampleMemCapacity(0));
memset(sampleOffA,0,256*sizeof(unsigned int)); memset(sampleOffA,0,256*sizeof(unsigned int));
memset(sampleOffB,0,256*sizeof(unsigned int)); memset(sampleOffB,0,256*sizeof(unsigned int));
@ -225,6 +229,11 @@ template<int ChanNum> class DivPlatformYM2610Base: public DivPlatformOPN {
size_t memPos=0; size_t memPos=0;
for (int i=0; i<parent->song.sampleLen; i++) { for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i]; DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOffA[i]=0;
continue;
}
int paddedLen=(s->lengthA+255)&(~0xff); int paddedLen=(s->lengthA+255)&(~0xff);
if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) { if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) {
memPos=(memPos+0xfffff)&0xf00000; memPos=(memPos+0xfffff)&0xf00000;
@ -238,9 +247,9 @@ template<int ChanNum> class DivPlatformYM2610Base: public DivPlatformOPN {
logW("out of ADPCM-A memory for sample %d!",i); logW("out of ADPCM-A memory for sample %d!",i);
} else { } else {
memcpy(adpcmAMem+memPos,s->dataA,paddedLen); memcpy(adpcmAMem+memPos,s->dataA,paddedLen);
sampleLoaded[0][i]=true;
} }
sampleOffA[i]=memPos; sampleOffA[i]=memPos;
sampleLoaded[0][i]=true;
memPos+=paddedLen; memPos+=paddedLen;
} }
adpcmAMemLen=memPos+256; adpcmAMemLen=memPos+256;
@ -250,6 +259,11 @@ template<int ChanNum> class DivPlatformYM2610Base: public DivPlatformOPN {
memPos=0; memPos=0;
for (int i=0; i<parent->song.sampleLen; i++) { for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i]; DivSample* s=parent->song.sample[i];
if (!s->renderOn[1][sysID]) {
sampleOffB[i]=0;
continue;
}
int paddedLen=(s->lengthB+255)&(~0xff); int paddedLen=(s->lengthB+255)&(~0xff);
if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) { if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) {
memPos=(memPos+0xfffff)&0xf00000; memPos=(memPos+0xfffff)&0xf00000;
@ -263,9 +277,9 @@ template<int ChanNum> class DivPlatformYM2610Base: public DivPlatformOPN {
logW("out of ADPCM-B memory for sample %d!",i); logW("out of ADPCM-B memory for sample %d!",i);
} else { } else {
memcpy(adpcmBMem+memPos,s->dataB,paddedLen); memcpy(adpcmBMem+memPos,s->dataB,paddedLen);
sampleLoaded[1][i]=true;
} }
sampleOffB[i]=memPos; sampleOffB[i]=memPos;
sampleLoaded[1][i]=true;
memPos+=paddedLen; memPos+=paddedLen;
} }
adpcmBMemLen=memPos+256; adpcmBMemLen=memPos+256;

View file

@ -426,13 +426,19 @@ bool DivPlatformYMZ280B::isSampleLoaded(int index, int sample) {
return sampleLoaded[sample]; return sampleLoaded[sample];
} }
void DivPlatformYMZ280B::renderSamples() { void DivPlatformYMZ280B::renderSamples(int sysID) {
memset(sampleMem,0,getSampleMemCapacity()); memset(sampleMem,0,getSampleMemCapacity());
memset(sampleOff,0,256*sizeof(unsigned int)); memset(sampleOff,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
size_t memPos=0; size_t memPos=0;
for (int i=0; i<parent->song.sampleLen; i++) { for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i]; DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOff[i]=0;
continue;
}
int length=s->getCurBufLen(); int length=s->getCurBufLen();
unsigned char* src=(unsigned char*)s->getCurBuf(); unsigned char* src=(unsigned char*)s->getCurBuf();
int actualLength=MIN((int)(getSampleMemCapacity()-memPos),length); int actualLength=MIN((int)(getSampleMemCapacity()-memPos),length);
@ -455,6 +461,7 @@ void DivPlatformYMZ280B::renderSamples() {
logW("out of YMZ280B PCM memory for sample %d!",i); logW("out of YMZ280B PCM memory for sample %d!",i);
break; break;
} }
sampleLoaded[i]=true;
} }
sampleMemLen=memPos; sampleMemLen=memPos;
} }

View file

@ -101,7 +101,7 @@ class DivPlatformYMZ280B: public DivDispatch {
size_t getSampleMemCapacity(int index = 0); size_t getSampleMemCapacity(int index = 0);
size_t getSampleMemUsage(int index = 0); size_t getSampleMemUsage(int index = 0);
bool isSampleLoaded(int index, int sample); bool isSampleLoaded(int index, int sample);
void renderSamples(); void renderSamples(int chipID);
void setFlags(const DivConfig& flags); void setFlags(const DivConfig& flags);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit(); void quit();

View file

@ -281,6 +281,7 @@ void FurnaceGUI::drawSampleEdit() {
memset(isChipVisible,0,32*sizeof(bool)); memset(isChipVisible,0,32*sizeof(bool));
memset(isTypeVisible,0,4*sizeof(bool)); memset(isTypeVisible,0,4*sizeof(bool));
memset(isMemVisible,0,32*4*sizeof(bool)); memset(isMemVisible,0,32*4*sizeof(bool));
memset(isMemWarning,0,32*4*sizeof(bool));
for (int i=0; i<e->song.systemLen; i++) { for (int i=0; i<e->song.systemLen; i++) {
DivDispatch* dispatch=e->getDispatch(i); DivDispatch* dispatch=e->getDispatch(i);
if (dispatch==NULL) continue; if (dispatch==NULL) continue;
@ -300,7 +301,7 @@ void FurnaceGUI::drawSampleEdit() {
if (selColumns<=1) { if (selColumns<=1) {
ImGui::Text("NO CHIPS LESS GOOO"); ImGui::Text("NO CHIPS LESS GOOO");
} else { } else {
if (ImGui::BeginTable("SEChipSel",selColumns,ImGuiTableFlags_SizingFixedSame|ImGuiTableFlags_ScrollX)) { if (ImGui::BeginTable("SEChipSel",selColumns,ImGuiTableFlags_SizingFixedSame)) {
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
for (int i=0; i<e->song.systemLen; i++) { for (int i=0; i<e->song.systemLen; i++) {
@ -356,6 +357,34 @@ void FurnaceGUI::drawSampleEdit() {
} }
ImGui::PopStyleColor(4); ImGui::PopStyleColor(4);
if (ImGui::IsItemHovered()) {
const char* memName=NULL;
size_t capacity=0;
size_t usage=0;
int totalFree=0;
DivDispatch* dispatch=e->getDispatch(j);
if (dispatch!=NULL) {
memName=dispatch->getSampleMemName(i);
capacity=dispatch->getSampleMemCapacity(i);
usage=dispatch->getSampleMemUsage(i);
if (usage<capacity) {
totalFree=capacity-usage;
}
}
String toolText;
if (memName==NULL) {
toolText=fmt::sprintf("%s\n%d bytes free",e->getSystemName(e->song.system[j]),totalFree);
} else {
toolText=fmt::sprintf("%s (%s)\n%d bytes free",e->getSystemName(e->song.system[j]),memName,totalFree);
}
if (isMemWarning[i][j] && sample->renderOn[i][j]) {
toolText+="\n\nnot enough memory for this sample!";
}
ImGui::SetTooltip("%s",toolText.c_str());
}
} }
} }
ImGui::EndTable(); ImGui::EndTable();