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)
- port presets to new format
- bug fixes
- (maybe) ExtCh FM macros?
- (maybe) advanced linear arpeggio? (run arp+slide simultaneously)

View File

@ -532,6 +532,13 @@ class DivDispatch {
*/
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.
* @param index the memory index.
@ -550,8 +557,9 @@ class DivDispatch {
/**
* 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.

View File

@ -1315,7 +1315,7 @@ void DivEngine::renderSamples() {
// step 2: render samples to dispatch
for (int i=0; i<song.systemLen; i++) {
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;
}
const char* DivDispatch::getSampleMemName(int index) {
return NULL;
}
size_t DivDispatch::getSampleMemUsage(int index) {
return 0;
}
bool DivDispatch::isSampleLoaded(int index, int sample) {
printf("you are calling.\n");
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];
}
void DivPlatformMSM6258::renderSamples() {
void DivPlatformMSM6258::renderSamples(int sysID) {
memset(adpcmMem,0,getSampleMemCapacity(0));
memset(sampleLoaded,0,256*sizeof(bool));
// sample data
size_t memPos=0;
@ -377,6 +378,8 @@ void DivPlatformMSM6258::renderSamples() {
if (sampleCount>128) sampleCount=128;
for (int i=0; i<sampleCount; i++) {
DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) continue;
int paddedLen=s->lengthVOX;
if (memPos>=getSampleMemCapacity(0)) {
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);
} else {
memcpy(adpcmMem+memPos,s->dataVOX,paddedLen);
sampleLoaded[i]=true;
}
memPos+=paddedLen;
}

View File

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

View File

@ -341,11 +341,12 @@ bool DivPlatformMSM6295::isSampleLoaded(int index, int sample) {
return sampleLoaded[sample];
}
void DivPlatformMSM6295::renderSamples() {
void DivPlatformMSM6295::renderSamples(int sysID) {
unsigned int sampleOffVOX[256];
memset(adpcmMem,0,getSampleMemCapacity(0));
memset(sampleOffVOX,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
// sample data
size_t memPos=128*8;
@ -353,6 +354,11 @@ void DivPlatformMSM6295::renderSamples() {
if (sampleCount>128) sampleCount=128;
for (int i=0; i<sampleCount; i++) {
DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOffVOX[i]=0;
continue;
}
int paddedLen=s->lengthVOX;
if (memPos>=getSampleMemCapacity(0)) {
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);
} else {
memcpy(adpcmMem+memPos,s->dataVOX,paddedLen);
sampleLoaded[i]=true;
}
sampleOffVOX[i]=memPos;
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 getSampleMemUsage(int index) 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 void quit() override;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -451,7 +451,7 @@ void DivPlatformSegaPCM::reset() {
}
}
void DivPlatformSegaPCM::renderSamples() {
void DivPlatformSegaPCM::renderSamples(int sysID) {
size_t memPos=0;
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 muteChannel(int ch, bool mute);
void notifyInsChange(int ins);
void renderSamples();
void renderSamples(int chipID);
void setFlags(const DivConfig& flags);
bool isStereo();
void poke(unsigned int addr, unsigned short val);

View File

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

View File

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

View File

@ -524,7 +524,7 @@ void DivPlatformSoundUnit::setFlags(const DivConfig& flags) {
sampleMemSize=flags.getInt("sampleMemSize",0);
su->Init(sampleMemSize?65536:8192,flags.getBool("pdm",false));
renderSamples();
renderSamples(sysIDCache);
}
void DivPlatformSoundUnit::poke(unsigned int addr, unsigned short val) {
@ -553,14 +553,20 @@ bool DivPlatformSoundUnit::isSampleLoaded(int index, int sample) {
return sampleLoaded[sample];
}
void DivPlatformSoundUnit::renderSamples() {
void DivPlatformSoundUnit::renderSamples(int sysID) {
memset(su->pcm,0,getSampleMemCapacity(0));
memset(sampleOffSU,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
size_t memPos=0;
for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i];
if (s->data8==NULL) continue;
if (!s->renderOn[0][sysID]) {
sampleOffSU[i]=0;
continue;
}
int paddedLen=s->length8;
if (memPos>=getSampleMemCapacity(0)) {
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);
} else {
memcpy(su->pcm+memPos,s->data8,paddedLen);
sampleLoaded[i]=true;
}
sampleOffSU[i]=memPos;
memPos+=paddedLen;
}
sampleMemLen=memPos;
sysIDCache=sysID;
}
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;
}
su=new SoundUnit();
sysIDCache=0;
setFlags(flags);
reset();
return 8;

View File

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

View File

@ -955,13 +955,19 @@ bool DivPlatformX1_010::isSampleLoaded(int index, int sample) {
return sampleLoaded[sample];
}
void DivPlatformX1_010::renderSamples() {
void DivPlatformX1_010::renderSamples(int sysID) {
memset(sampleMem,0,getSampleMemCapacity());
memset(sampleOffX1,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
size_t memPos=0;
for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOffX1[i]=0;
continue;
}
int paddedLen=(s->length8+4095)&(~0xfff);
if (isBanked) {
// 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);
} else {
memcpy(sampleMem+memPos,s->data8,paddedLen);
sampleLoaded[i]=true;
}
sampleOffX1[i]=memPos;
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 getSampleMemUsage(int index = 0);
bool isSampleLoaded(int index, int sample);
void renderSamples();
void renderSamples(int chipID);
const char** getRegisterSheet();
void setBanked(bool banked);
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];
}
void DivPlatformYM2608::renderSamples() {
void DivPlatformYM2608::renderSamples(int sysID) {
memset(adpcmBMem,0,getSampleMemCapacity(0));
memset(sampleOffB,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
size_t memPos=0;
for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOffB[i]=0;
continue;
}
int paddedLen=(s->lengthB+255)&(~0xff);
if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) {
memPos=(memPos+0xfffff)&0xf00000;
@ -1362,6 +1368,7 @@ void DivPlatformYM2608::renderSamples() {
logW("out of ADPCM memory for sample %d!",i);
} else {
memcpy(adpcmBMem+memPos,s->dataB,paddedLen);
sampleLoaded[i]=true;
}
sampleOffB[i]=memPos;
memPos+=paddedLen;

View File

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

View File

@ -206,6 +206,10 @@ template<int ChanNum> class DivPlatformYM2610Base: public DivPlatformOPN {
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) {
return index == 0 ? adpcmAMemLen : index == 1 ? adpcmBMemLen : 0;
}
@ -216,7 +220,7 @@ template<int ChanNum> class DivPlatformYM2610Base: public DivPlatformOPN {
return sampleLoaded[index][sample];
}
void renderSamples() {
void renderSamples(int sysID) {
memset(adpcmAMem,0,getSampleMemCapacity(0));
memset(sampleOffA,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;
for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOffA[i]=0;
continue;
}
int paddedLen=(s->lengthA+255)&(~0xff);
if ((memPos&0xf00000)!=((memPos+paddedLen)&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);
} else {
memcpy(adpcmAMem+memPos,s->dataA,paddedLen);
sampleLoaded[0][i]=true;
}
sampleOffA[i]=memPos;
sampleLoaded[0][i]=true;
memPos+=paddedLen;
}
adpcmAMemLen=memPos+256;
@ -250,6 +259,11 @@ template<int ChanNum> class DivPlatformYM2610Base: public DivPlatformOPN {
memPos=0;
for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i];
if (!s->renderOn[1][sysID]) {
sampleOffB[i]=0;
continue;
}
int paddedLen=(s->lengthB+255)&(~0xff);
if ((memPos&0xf00000)!=((memPos+paddedLen)&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);
} else {
memcpy(adpcmBMem+memPos,s->dataB,paddedLen);
sampleLoaded[1][i]=true;
}
sampleOffB[i]=memPos;
sampleLoaded[1][i]=true;
memPos+=paddedLen;
}
adpcmBMemLen=memPos+256;

View File

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

View File

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

View File

@ -281,6 +281,7 @@ void FurnaceGUI::drawSampleEdit() {
memset(isChipVisible,0,32*sizeof(bool));
memset(isTypeVisible,0,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++) {
DivDispatch* dispatch=e->getDispatch(i);
if (dispatch==NULL) continue;
@ -300,7 +301,7 @@ void FurnaceGUI::drawSampleEdit() {
if (selColumns<=1) {
ImGui::Text("NO CHIPS LESS GOOO");
} else {
if (ImGui::BeginTable("SEChipSel",selColumns,ImGuiTableFlags_SizingFixedSame|ImGuiTableFlags_ScrollX)) {
if (ImGui::BeginTable("SEChipSel",selColumns,ImGuiTableFlags_SizingFixedSame)) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
for (int i=0; i<e->song.systemLen; i++) {
@ -356,6 +357,34 @@ void FurnaceGUI::drawSampleEdit() {
}
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();