Merge pull request #410 from grauw/dispatch-render-samples
Move renderSamples() to DivDispatch implementations.
This commit is contained in:
commit
5adc29906a
|
@ -440,6 +440,26 @@ class DivDispatch {
|
||||||
*/
|
*/
|
||||||
virtual const char** getRegisterSheet();
|
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.
|
* initialize this DivDispatch.
|
||||||
* @param parent the parent DivEngine.
|
* @param parent the parent DivEngine.
|
||||||
|
|
|
@ -506,118 +506,12 @@ void DivEngine::renderSamples() {
|
||||||
song.sample[i]->render();
|
song.sample[i]->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
// step 2: allocate ADPCM-A samples
|
// step 2: render samples to dispatch
|
||||||
if (adpcmAMem==NULL) adpcmAMem=new unsigned char[16777216];
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
|
if (disCont[i].dispatch!=NULL) {
|
||||||
size_t memPos=0;
|
disCont[i].dispatch->renderSamples();
|
||||||
for (int i=0; i<song.sampleLen; i++) {
|
|
||||||
DivSample* s=song.sample[i];
|
|
||||||
int paddedLen=(s->lengthA+255)&(~0xff);
|
|
||||||
if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) {
|
|
||||||
memPos=(memPos+0xfffff)&0xf00000;
|
|
||||||
}
|
|
||||||
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; i<song.sampleLen; i++) {
|
|
||||||
DivSample* s=song.sample[i];
|
|
||||||
int paddedLen=(s->lengthB+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; i<song.sampleLen; i++) {
|
|
||||||
DivSample* s=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>=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; i<length; i++) {
|
|
||||||
qsoundMem[(memPos+i)^0x8000]=s->data8[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; i<song.sampleLen; i++) {
|
|
||||||
DivSample* s=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>=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<int>& desc) {
|
String DivEngine::encodeSysDesc(std::vector<int>& desc) {
|
||||||
|
@ -725,11 +619,11 @@ void DivEngine::createNew(const int* description) {
|
||||||
initSongWithDesc(description);
|
initSongWithDesc(description);
|
||||||
}
|
}
|
||||||
recalcChans();
|
recalcChans();
|
||||||
renderSamples();
|
|
||||||
saveLock.unlock();
|
saveLock.unlock();
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
initDispatch();
|
initDispatch();
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
|
renderSamples();
|
||||||
reset();
|
reset();
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
}
|
}
|
||||||
|
@ -967,6 +861,11 @@ DivSample* DivEngine::getSample(int index) {
|
||||||
return song.sample[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) {
|
void DivEngine::setLoops(int loops) {
|
||||||
remainingLoops=loops;
|
remainingLoops=loops;
|
||||||
}
|
}
|
||||||
|
@ -2812,6 +2711,7 @@ bool DivEngine::init() {
|
||||||
oscBuf[1]=new float[32768];
|
oscBuf[1]=new float[32768];
|
||||||
|
|
||||||
initDispatch();
|
initDispatch();
|
||||||
|
renderSamples();
|
||||||
reset();
|
reset();
|
||||||
active=true;
|
active=true;
|
||||||
|
|
||||||
|
|
|
@ -422,6 +422,7 @@ class DivEngine {
|
||||||
DivInstrument* getIns(int index, DivInstrumentType fallbackType=DIV_INS_FM);
|
DivInstrument* getIns(int index, DivInstrumentType fallbackType=DIV_INS_FM);
|
||||||
DivWavetable* getWave(int index);
|
DivWavetable* getWave(int index);
|
||||||
DivSample* getSample(int index);
|
DivSample* getSample(int index);
|
||||||
|
DivDispatch* getDispatch(int index);
|
||||||
// parse system setup description
|
// parse system setup description
|
||||||
String encodeSysDesc(std::vector<int>& desc);
|
String encodeSysDesc(std::vector<int>& desc);
|
||||||
std::vector<int> decodeSysDesc(String desc);
|
std::vector<int> decodeSysDesc(String desc);
|
||||||
|
@ -849,19 +850,6 @@ class DivEngine {
|
||||||
// terminate the engine.
|
// terminate the engine.
|
||||||
bool quit();
|
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():
|
DivEngine():
|
||||||
output(NULL),
|
output(NULL),
|
||||||
exportThread(NULL),
|
exportThread(NULL),
|
||||||
|
@ -935,19 +923,7 @@ class DivEngine {
|
||||||
oscSize(1),
|
oscSize(1),
|
||||||
oscReadPos(0),
|
oscReadPos(0),
|
||||||
oscWritePos(0),
|
oscWritePos(0),
|
||||||
tickMult(1),
|
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) {
|
|
||||||
memset(isMuted,0,DIV_MAX_CHANS*sizeof(bool));
|
memset(isMuted,0,DIV_MAX_CHANS*sizeof(bool));
|
||||||
memset(keyHit,0,DIV_MAX_CHANS*sizeof(bool));
|
memset(keyHit,0,DIV_MAX_CHANS*sizeof(bool));
|
||||||
memset(dispatchChanOfChan,0,DIV_MAX_CHANS*sizeof(int));
|
memset(dispatchChanOfChan,0,DIV_MAX_CHANS*sizeof(int));
|
||||||
|
|
|
@ -899,12 +899,14 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
song.unload();
|
song.unload();
|
||||||
song=ds;
|
song=ds;
|
||||||
recalcChans();
|
recalcChans();
|
||||||
renderSamples();
|
|
||||||
saveLock.unlock();
|
saveLock.unlock();
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
if (active) {
|
if (active) {
|
||||||
initDispatch();
|
initDispatch();
|
||||||
syncReset();
|
BUSY_BEGIN;
|
||||||
|
renderSamples();
|
||||||
|
reset();
|
||||||
|
BUSY_END;
|
||||||
}
|
}
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
logE("premature end of file!");
|
logE("premature end of file!");
|
||||||
|
@ -1596,12 +1598,14 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
song.unload();
|
song.unload();
|
||||||
song=ds;
|
song=ds;
|
||||||
recalcChans();
|
recalcChans();
|
||||||
renderSamples();
|
|
||||||
saveLock.unlock();
|
saveLock.unlock();
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
if (active) {
|
if (active) {
|
||||||
initDispatch();
|
initDispatch();
|
||||||
syncReset();
|
BUSY_BEGIN;
|
||||||
|
renderSamples();
|
||||||
|
reset();
|
||||||
|
BUSY_END;
|
||||||
}
|
}
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
logE("premature end of file!");
|
logE("premature end of file!");
|
||||||
|
@ -2005,12 +2009,14 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
||||||
song.unload();
|
song.unload();
|
||||||
song=ds;
|
song=ds;
|
||||||
recalcChans();
|
recalcChans();
|
||||||
renderSamples();
|
|
||||||
saveLock.unlock();
|
saveLock.unlock();
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
if (active) {
|
if (active) {
|
||||||
initDispatch();
|
initDispatch();
|
||||||
syncReset();
|
BUSY_BEGIN;
|
||||||
|
renderSamples();
|
||||||
|
reset();
|
||||||
|
BUSY_END;
|
||||||
}
|
}
|
||||||
success=true;
|
success=true;
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
|
|
|
@ -141,6 +141,22 @@ const char** DivDispatch::getRegisterSheet() {
|
||||||
return NULL;
|
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) {
|
int DivDispatch::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -268,8 +268,6 @@ const char* DivPlatformQSound::getEffectName(unsigned char effect) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
void DivPlatformQSound::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
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; h<start+len; h++) {
|
for (size_t h=start; h<start+len; h++) {
|
||||||
qsound_update(&chip);
|
qsound_update(&chip);
|
||||||
bufL[h]=chip.out[0];
|
bufL[h]=chip.out[0];
|
||||||
|
@ -638,6 +636,51 @@ int DivPlatformQSound::getRegisterPoolDepth() {
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const void* DivPlatformQSound::getSampleMem(int index) {
|
||||||
|
return index == 0 ? sampleMem : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t DivPlatformQSound::getSampleMemCapacity(int index) {
|
||||||
|
return index == 0 ? 16777216 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t DivPlatformQSound::getSampleMemUsage(int index) {
|
||||||
|
return index == 0 ? sampleMemLen : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DivPlatformQSound::renderSamples() {
|
||||||
|
memset(sampleMem,0,getSampleMemCapacity());
|
||||||
|
|
||||||
|
size_t memPos=0;
|
||||||
|
for (int i=0; i<parent->song.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; i<getSampleMemCapacity()-(memPos+length); i++) {
|
||||||
|
sampleMem[(memPos+i)^0x8000]=s->data8[i];
|
||||||
|
}
|
||||||
|
logW("out of QSound PCM memory for sample %d!",i);
|
||||||
|
} else {
|
||||||
|
for (int i=0; i<length; i++) {
|
||||||
|
sampleMem[(memPos+i)^0x8000]=s->data8[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s->offQSound=memPos^0x8000;
|
||||||
|
memPos+=length+16;
|
||||||
|
}
|
||||||
|
sampleMemLen=memPos+256;
|
||||||
|
}
|
||||||
|
|
||||||
int DivPlatformQSound::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
int DivPlatformQSound::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||||
parent=p;
|
parent=p;
|
||||||
dumpWrites=false;
|
dumpWrites=false;
|
||||||
|
@ -651,8 +694,10 @@ int DivPlatformQSound::init(DivEngine* p, int channels, int sugRate, unsigned in
|
||||||
|
|
||||||
chipClock=60000000;
|
chipClock=60000000;
|
||||||
rate = qsound_start(&chip, chipClock);
|
rate = qsound_start(&chip, chipClock);
|
||||||
chip.rom_data = (unsigned char*)&chip.rom_mask;
|
sampleMem=new unsigned char[getSampleMemCapacity()];
|
||||||
chip.rom_mask = 0;
|
sampleMemLen=0;
|
||||||
|
chip.rom_data=sampleMem;
|
||||||
|
chip.rom_mask=0xffffff;
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
for (int i=0; i<19; i++) {
|
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() {
|
void DivPlatformQSound::quit() {
|
||||||
|
delete[] sampleMem;
|
||||||
for (int i=0; i<19; i++) {
|
for (int i=0; i<19; i++) {
|
||||||
delete oscBuf[i];
|
delete oscBuf[i];
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,8 @@ class DivPlatformQSound: public DivDispatch {
|
||||||
int echoDelay;
|
int echoDelay;
|
||||||
int echoFeedback;
|
int echoFeedback;
|
||||||
|
|
||||||
|
unsigned char* sampleMem;
|
||||||
|
size_t sampleMemLen;
|
||||||
struct qsound_chip chip;
|
struct qsound_chip chip;
|
||||||
unsigned short regPool[512];
|
unsigned short regPool[512];
|
||||||
|
|
||||||
|
@ -94,6 +96,10 @@ class DivPlatformQSound: public DivDispatch {
|
||||||
void poke(std::vector<DivRegWrite>& wlist);
|
void poke(std::vector<DivRegWrite>& wlist);
|
||||||
const char** getRegisterSheet();
|
const char** getRegisterSheet();
|
||||||
const char* getEffectName(unsigned char effect);
|
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);
|
int init(DivEngine* parent, int channels, int sugRate, unsigned int flags);
|
||||||
void quit();
|
void quit();
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "x1_010.h"
|
#include "x1_010.h"
|
||||||
#include "../engine.h"
|
#include "../engine.h"
|
||||||
|
#include "../../ta-log.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
//#define rWrite(a,v) pendingWrites[a]=v;
|
//#define rWrite(a,v) pendingWrites[a]=v;
|
||||||
|
@ -909,6 +910,48 @@ void DivPlatformX1_010::poke(std::vector<DivRegWrite>& wlist) {
|
||||||
for (DivRegWrite& i: wlist) rWrite(i.addr,i.val);
|
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; i<parent->song.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) {
|
int DivPlatformX1_010::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||||
parent=p;
|
parent=p;
|
||||||
dumpWrites=false;
|
dumpWrites=false;
|
||||||
|
@ -919,7 +962,9 @@ int DivPlatformX1_010::init(DivEngine* p, int channels, int sugRate, unsigned in
|
||||||
oscBuf[i]=new DivDispatchOscBuffer;
|
oscBuf[i]=new DivDispatchOscBuffer;
|
||||||
}
|
}
|
||||||
setFlags(flags);
|
setFlags(flags);
|
||||||
intf.parent=parent;
|
sampleMem=new unsigned char[getSampleMemCapacity()];
|
||||||
|
sampleMemLen=0;
|
||||||
|
intf.memory=sampleMem;
|
||||||
x1_010=new x1_010_core(intf);
|
x1_010=new x1_010_core(intf);
|
||||||
x1_010->reset();
|
x1_010->reset();
|
||||||
reset();
|
reset();
|
||||||
|
@ -931,6 +976,7 @@ void DivPlatformX1_010::quit() {
|
||||||
delete oscBuf[i];
|
delete oscBuf[i];
|
||||||
}
|
}
|
||||||
delete x1_010;
|
delete x1_010;
|
||||||
|
delete[] sampleMem;
|
||||||
}
|
}
|
||||||
|
|
||||||
DivPlatformX1_010::~DivPlatformX1_010() {
|
DivPlatformX1_010::~DivPlatformX1_010() {
|
||||||
|
|
|
@ -28,13 +28,13 @@
|
||||||
|
|
||||||
class DivX1_010Interface: public x1_010_mem_intf {
|
class DivX1_010Interface: public x1_010_mem_intf {
|
||||||
public:
|
public:
|
||||||
DivEngine* parent;
|
unsigned char* memory;
|
||||||
int sampleBank;
|
int sampleBank;
|
||||||
virtual u8 read_byte(u32 address) override {
|
virtual u8 read_byte(u32 address) override {
|
||||||
if (parent->x1_010Mem==NULL) return 0;
|
if (memory==NULL) return 0;
|
||||||
return parent->x1_010Mem[address & 0xfffff];
|
return memory[address & 0xfffff];
|
||||||
}
|
}
|
||||||
DivX1_010Interface(): parent(NULL), sampleBank(0) {}
|
DivX1_010Interface(): memory(NULL), sampleBank(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DivPlatformX1_010: public DivDispatch {
|
class DivPlatformX1_010: public DivDispatch {
|
||||||
|
@ -115,6 +115,8 @@ class DivPlatformX1_010: public DivDispatch {
|
||||||
DivDispatchOscBuffer* oscBuf[16];
|
DivDispatchOscBuffer* oscBuf[16];
|
||||||
bool isMuted[16];
|
bool isMuted[16];
|
||||||
bool stereo=false;
|
bool stereo=false;
|
||||||
|
unsigned char* sampleMem;
|
||||||
|
size_t sampleMemLen;
|
||||||
unsigned char sampleBank;
|
unsigned char sampleBank;
|
||||||
DivX1_010Interface intf;
|
DivX1_010Interface intf;
|
||||||
x1_010_core* x1_010;
|
x1_010_core* x1_010;
|
||||||
|
@ -141,6 +143,10 @@ class DivPlatformX1_010: public DivDispatch {
|
||||||
void notifyInsDeletion(void* ins);
|
void notifyInsDeletion(void* ins);
|
||||||
void poke(unsigned int addr, unsigned short val);
|
void poke(unsigned int addr, unsigned short val);
|
||||||
void poke(std::vector<DivRegWrite>& wlist);
|
void poke(std::vector<DivRegWrite>& 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** getRegisterSheet();
|
||||||
const char* getEffectName(unsigned char effect);
|
const char* getEffectName(unsigned char effect);
|
||||||
int init(DivEngine* parent, int channels, int sugRate, unsigned int flags);
|
int init(DivEngine* parent, int channels, int sugRate, unsigned int flags);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "ym2610.h"
|
#include "ym2610.h"
|
||||||
#include "sound/ymfm/ymfm.h"
|
#include "sound/ymfm/ymfm.h"
|
||||||
#include "../engine.h"
|
#include "../engine.h"
|
||||||
|
#include "../../ta-log.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
@ -245,6 +246,85 @@ const char* regCheatSheetYM2610[]={
|
||||||
NULL
|
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; i<parent->song.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; i<parent->song.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() {
|
const char** DivPlatformYM2610::getRegisterSheet() {
|
||||||
return regCheatSheetYM2610;
|
return regCheatSheetYM2610;
|
||||||
}
|
}
|
||||||
|
@ -1185,7 +1265,7 @@ void DivPlatformYM2610::setSkipRegisterWrites(bool value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformYM2610::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
int DivPlatformYM2610::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||||
parent=p;
|
DivPlatformYM2610Base::init(p, channels, sugRate, flags);
|
||||||
dumpWrites=false;
|
dumpWrites=false;
|
||||||
skipRegisterWrites=false;
|
skipRegisterWrites=false;
|
||||||
for (int i=0; i<14; i++) {
|
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++) {
|
for (int i=0; i<14; i++) {
|
||||||
oscBuf[i]->rate=rate;
|
oscBuf[i]->rate=rate;
|
||||||
}
|
}
|
||||||
iface.parent=parent;
|
|
||||||
iface.sampleBank=0;
|
|
||||||
fm=new ymfm::ym2610(iface);
|
fm=new ymfm::ym2610(iface);
|
||||||
// YM2149, 2MHz
|
// YM2149, 2MHz
|
||||||
ay=new DivPlatformAY8910;
|
ay=new DivPlatformAY8910;
|
||||||
|
@ -1215,6 +1293,7 @@ void DivPlatformYM2610::quit() {
|
||||||
ay->quit();
|
ay->quit();
|
||||||
delete ay;
|
delete ay;
|
||||||
delete fm;
|
delete fm;
|
||||||
|
DivPlatformYM2610Base::quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
DivPlatformYM2610::~DivPlatformYM2610() {
|
DivPlatformYM2610::~DivPlatformYM2610() {
|
||||||
|
|
|
@ -27,14 +27,32 @@
|
||||||
|
|
||||||
class DivYM2610Interface: public ymfm::ymfm_interface {
|
class DivYM2610Interface: public ymfm::ymfm_interface {
|
||||||
public:
|
public:
|
||||||
DivEngine* parent;
|
unsigned char* adpcmAMem;
|
||||||
|
unsigned char* adpcmBMem;
|
||||||
int sampleBank;
|
int sampleBank;
|
||||||
uint8_t ymfm_external_read(ymfm::access_class type, uint32_t address);
|
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);
|
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:
|
protected:
|
||||||
const unsigned short chanOffs[4]={
|
const unsigned short chanOffs[4]={
|
||||||
0x01, 0x02, 0x101, 0x102
|
0x01, 0x02, 0x101, 0x102
|
||||||
|
@ -93,7 +111,6 @@ class DivPlatformYM2610: public DivDispatch {
|
||||||
std::queue<QueuedWrite> writes;
|
std::queue<QueuedWrite> writes;
|
||||||
ymfm::ym2610* fm;
|
ymfm::ym2610* fm;
|
||||||
ymfm::ym2610::output_data fmout;
|
ymfm::ym2610::output_data fmout;
|
||||||
DivYM2610Interface iface;
|
|
||||||
|
|
||||||
DivPlatformAY8910* ay;
|
DivPlatformAY8910* ay;
|
||||||
unsigned char regPool[512];
|
unsigned char regPool[512];
|
||||||
|
|
|
@ -24,13 +24,11 @@
|
||||||
uint8_t DivYM2610Interface::ymfm_external_read(ymfm::access_class type, uint32_t address) {
|
uint8_t DivYM2610Interface::ymfm_external_read(ymfm::access_class type, uint32_t address) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ymfm::ACCESS_ADPCM_A:
|
case ymfm::ACCESS_ADPCM_A:
|
||||||
if (parent->adpcmAMem==NULL) return 0;
|
if (adpcmAMem==NULL) return 0;
|
||||||
if ((address&0xffffff)>=parent->adpcmAMemLen) return 0;
|
return adpcmAMem[address&0xffffff];
|
||||||
return parent->adpcmAMem[address&0xffffff];
|
|
||||||
case ymfm::ACCESS_ADPCM_B:
|
case ymfm::ACCESS_ADPCM_B:
|
||||||
if (parent->adpcmBMem==NULL) return 0;
|
if (adpcmBMem==NULL) return 0;
|
||||||
if ((address&0xffffff)>=parent->adpcmBMemLen) return 0;
|
return adpcmBMem[address&0xffffff];
|
||||||
return parent->adpcmBMem[address&0xffffff];
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1243,7 +1243,7 @@ void DivPlatformYM2610B::setSkipRegisterWrites(bool value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformYM2610B::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
int DivPlatformYM2610B::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||||
parent=p;
|
DivPlatformYM2610Base::init(p, channels, sugRate, flags);
|
||||||
dumpWrites=false;
|
dumpWrites=false;
|
||||||
skipRegisterWrites=false;
|
skipRegisterWrites=false;
|
||||||
for (int i=0; i<16; i++) {
|
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++) {
|
for (int i=0; i<16; i++) {
|
||||||
oscBuf[i]->rate=rate;
|
oscBuf[i]->rate=rate;
|
||||||
}
|
}
|
||||||
iface.parent=parent;
|
|
||||||
iface.sampleBank=0;
|
|
||||||
fm=new ymfm::ym2610b(iface);
|
fm=new ymfm::ym2610b(iface);
|
||||||
// YM2149, 2MHz
|
// YM2149, 2MHz
|
||||||
ay=new DivPlatformAY8910;
|
ay=new DivPlatformAY8910;
|
||||||
|
@ -1273,6 +1271,7 @@ void DivPlatformYM2610B::quit() {
|
||||||
ay->quit();
|
ay->quit();
|
||||||
delete ay;
|
delete ay;
|
||||||
delete fm;
|
delete fm;
|
||||||
|
DivPlatformYM2610Base::quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
DivPlatformYM2610B::~DivPlatformYM2610B() {
|
DivPlatformYM2610B::~DivPlatformYM2610B() {
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
#include "ym2610.h"
|
#include "ym2610.h"
|
||||||
|
|
||||||
class DivPlatformYM2610B: public DivDispatch {
|
class DivPlatformYM2610B: public DivPlatformYM2610Base {
|
||||||
protected:
|
protected:
|
||||||
const unsigned short chanOffs[6]={
|
const unsigned short chanOffs[6]={
|
||||||
0x00, 0x01, 0x02, 0x100, 0x101, 0x102
|
0x00, 0x01, 0x02, 0x100, 0x101, 0x102
|
||||||
|
@ -85,7 +85,6 @@ class DivPlatformYM2610B: public DivDispatch {
|
||||||
std::queue<QueuedWrite> writes;
|
std::queue<QueuedWrite> writes;
|
||||||
ymfm::ym2610b* fm;
|
ymfm::ym2610b* fm;
|
||||||
ymfm::ym2610b::output_data fmout;
|
ymfm::ym2610b::output_data fmout;
|
||||||
DivYM2610Interface iface;
|
|
||||||
unsigned char regPool[512];
|
unsigned char regPool[512];
|
||||||
unsigned char lastBusy;
|
unsigned char lastBusy;
|
||||||
|
|
||||||
|
|
|
@ -713,10 +713,10 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) {
|
||||||
bool writeDACSamples=false;
|
bool writeDACSamples=false;
|
||||||
bool writeNESSamples=false;
|
bool writeNESSamples=false;
|
||||||
bool writePCESamples=false;
|
bool writePCESamples=false;
|
||||||
int writeADPCM=0;
|
DivDispatch* writeADPCM[2]={NULL,NULL};
|
||||||
int writeSegaPCM=0;
|
int writeSegaPCM=0;
|
||||||
int writeX1010=0;
|
DivDispatch* writeX1010[2]={NULL,NULL};
|
||||||
int writeQSound=0;
|
DivDispatch* writeQSound[2]={NULL,NULL};
|
||||||
|
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
willExport[i]=false;
|
willExport[i]=false;
|
||||||
|
@ -805,11 +805,11 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) {
|
||||||
if (!hasX1) {
|
if (!hasX1) {
|
||||||
hasX1=disCont[i].dispatch->chipClock;
|
hasX1=disCont[i].dispatch->chipClock;
|
||||||
willExport[i]=true;
|
willExport[i]=true;
|
||||||
writeX1010=1;
|
writeX1010[0]=disCont[i].dispatch;
|
||||||
} else if (!(hasX1&0x40000000)) {
|
} else if (!(hasX1&0x40000000)) {
|
||||||
isSecond[i]=true;
|
isSecond[i]=true;
|
||||||
willExport[i]=true;
|
willExport[i]=true;
|
||||||
writeX1010=2;
|
writeX1010[1]=disCont[i].dispatch;
|
||||||
hasX1|=0x40000000;
|
hasX1|=0x40000000;
|
||||||
howManyChips++;
|
howManyChips++;
|
||||||
}
|
}
|
||||||
|
@ -823,11 +823,11 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) {
|
||||||
if (!hasOPNB) {
|
if (!hasOPNB) {
|
||||||
hasOPNB=disCont[i].dispatch->chipClock;
|
hasOPNB=disCont[i].dispatch->chipClock;
|
||||||
willExport[i]=true;
|
willExport[i]=true;
|
||||||
writeADPCM=1;
|
writeADPCM[0]=disCont[i].dispatch;
|
||||||
} else if (!(hasOPNB&0x40000000)) {
|
} else if (!(hasOPNB&0x40000000)) {
|
||||||
isSecond[i]=true;
|
isSecond[i]=true;
|
||||||
willExport[i]=true;
|
willExport[i]=true;
|
||||||
writeADPCM=2;
|
writeADPCM[1]=disCont[i].dispatch;
|
||||||
hasOPNB|=0x40000000;
|
hasOPNB|=0x40000000;
|
||||||
howManyChips++;
|
howManyChips++;
|
||||||
}
|
}
|
||||||
|
@ -929,11 +929,11 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) {
|
||||||
// not be able to handle the 64kb sample bank trick
|
// not be able to handle the 64kb sample bank trick
|
||||||
hasQSound=disCont[i].dispatch->chipClock;
|
hasQSound=disCont[i].dispatch->chipClock;
|
||||||
willExport[i]=true;
|
willExport[i]=true;
|
||||||
writeQSound=1;
|
writeQSound[0]=disCont[i].dispatch;
|
||||||
} else if (!(hasQSound&0x40000000)) {
|
} else if (!(hasQSound&0x40000000)) {
|
||||||
isSecond[i]=true;
|
isSecond[i]=true;
|
||||||
willExport[i]=false;
|
willExport[i]=false;
|
||||||
writeQSound=2;
|
writeQSound[1]=disCont[i].dispatch;
|
||||||
addWarning("dual QSound is not supported by the VGM format");
|
addWarning("dual QSound is not supported by the VGM format");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1249,56 +1249,55 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) {
|
||||||
delete[] pcmMem;
|
delete[] pcmMem;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adpcmAMemLen>0) {
|
for (int i=0; i<2; i++) {
|
||||||
for (int i=0; i<writeADPCM; i++) {
|
if (writeADPCM[i]!=NULL && writeADPCM[i]->getSampleMemUsage(0)>0) {
|
||||||
w->writeC(0x67);
|
w->writeC(0x67);
|
||||||
w->writeC(0x66);
|
w->writeC(0x66);
|
||||||
w->writeC(0x82);
|
w->writeC(0x82);
|
||||||
w->writeI((adpcmAMemLen+8)|(i*0x80000000));
|
w->writeI((writeADPCM[i]->getSampleMemUsage(0)+8)|(i*0x80000000));
|
||||||
w->writeI(adpcmAMemLen);
|
w->writeI(writeADPCM[i]->getSampleMemCapacity(0));
|
||||||
w->writeI(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; i<2; i++) {
|
||||||
for (int i=0; i<writeADPCM; i++) {
|
if (writeADPCM[i]!=NULL && writeADPCM[i]->getSampleMemUsage(1)>0) {
|
||||||
w->writeC(0x67);
|
w->writeC(0x67);
|
||||||
w->writeC(0x66);
|
w->writeC(0x66);
|
||||||
w->writeC(0x83);
|
w->writeC(0x83);
|
||||||
w->writeI((adpcmBMemLen+8)|(i*0x80000000));
|
w->writeI((writeADPCM[i]->getSampleMemUsage(1)+8)|(i*0x80000000));
|
||||||
w->writeI(adpcmBMemLen);
|
w->writeI(writeADPCM[i]->getSampleMemCapacity(1));
|
||||||
w->writeI(0);
|
w->writeI(0);
|
||||||
w->write(adpcmBMem,adpcmBMemLen);
|
w->write(writeADPCM[i]->getSampleMem(1),writeADPCM[i]->getSampleMemUsage(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qsoundMemLen>0) {
|
for (int i=0; i<2; i++) {
|
||||||
// always write a whole bank
|
if (writeQSound[i]!=NULL && writeQSound[i]->getSampleMemUsage()>0) {
|
||||||
unsigned int blockSize=(qsoundMemLen+0xffff)&(~0xffff);
|
unsigned int blockSize=(writeQSound[i]->getSampleMemUsage()+0xffff)&(~0xffff);
|
||||||
if (blockSize > 0x1000000) {
|
if (blockSize > 0x1000000) {
|
||||||
blockSize = 0x1000000;
|
blockSize = 0x1000000;
|
||||||
}
|
}
|
||||||
for (int i=0; i<writeQSound; i++) {
|
|
||||||
w->writeC(0x67);
|
w->writeC(0x67);
|
||||||
w->writeC(0x66);
|
w->writeC(0x66);
|
||||||
w->writeC(0x8F);
|
w->writeC(0x8F);
|
||||||
w->writeI((blockSize+8)|(i*0x80000000));
|
w->writeI((blockSize+8)|(i*0x80000000));
|
||||||
w->writeI(0x1000000);
|
w->writeI(writeQSound[i]->getSampleMemCapacity());
|
||||||
w->writeI(0);
|
w->writeI(0);
|
||||||
w->write(qsoundMem,blockSize);
|
w->write(writeQSound[i]->getSampleMem(),blockSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x1_010MemLen>0) {
|
for (int i=0; i<2; i++) {
|
||||||
for (int i=0; i<writeX1010; i++) {
|
if (writeX1010[i]!=NULL && writeX1010[i]->getSampleMemUsage()>0) {
|
||||||
w->writeC(0x67);
|
w->writeC(0x67);
|
||||||
w->writeC(0x66);
|
w->writeC(0x66);
|
||||||
w->writeC(0x91);
|
w->writeC(0x91);
|
||||||
w->writeI((x1_010MemLen+8)|(i*0x80000000));
|
w->writeI((writeX1010[i]->getSampleMemUsage()+8)|(i*0x80000000));
|
||||||
w->writeI(x1_010MemLen);
|
w->writeI(writeX1010[i]->getSampleMemCapacity());
|
||||||
w->writeI(0);
|
w->writeI(0);
|
||||||
w->write(x1_010Mem,x1_010MemLen);
|
w->write(writeX1010[i]->getSampleMem(),writeX1010[i]->getSampleMemUsage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,22 +28,17 @@ void FurnaceGUI::drawStats() {
|
||||||
}
|
}
|
||||||
if (!statsOpen) return;
|
if (!statsOpen) return;
|
||||||
if (ImGui::Begin("Statistics",&statsOpen)) {
|
if (ImGui::Begin("Statistics",&statsOpen)) {
|
||||||
String adpcmAUsage=fmt::sprintf("%d/16384KB",e->adpcmAMemLen/1024);
|
for (int i=0; i<e->song.systemLen; i++) {
|
||||||
String adpcmBUsage=fmt::sprintf("%d/16384KB",e->adpcmBMemLen/1024);
|
DivDispatch* dispatch=e->getDispatch(i);
|
||||||
String qsoundUsage=fmt::sprintf("%d/16384KB",e->qsoundMemLen/1024);
|
for (int j=0; dispatch!=NULL && dispatch->getSampleMemCapacity(j)>0; j++) {
|
||||||
String x1_010Usage=fmt::sprintf("%d/1024KB",e->x1_010MemLen/1024);
|
size_t capacity=dispatch->getSampleMemCapacity(j);
|
||||||
ImGui::Text("ADPCM-A");
|
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::SameLine();
|
||||||
ImGui::ProgressBar(((float)e->adpcmAMemLen)/16777216.0f,ImVec2(-FLT_MIN,0),adpcmAUsage.c_str());
|
ImGui::ProgressBar(((float)usage)/((float)capacity),ImVec2(-FLT_MIN,0),usageStr.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());
|
|
||||||
}
|
}
|
||||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_STATS;
|
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_STATS;
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
Loading…
Reference in New Issue