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

# Conflicts:
#	src/gui/insEdit.cpp
This commit is contained in:
Waldemar Pawlaszek 2022-02-22 09:13:49 +01:00
commit 79e53cfd10
38 changed files with 537 additions and 98 deletions

View file

@ -206,15 +206,27 @@ class DivDispatch {
* @return a pointer, or NULL.
*/
virtual void* getChanState(int chan);
/**
* get the register pool of this dispatch.
* @return a pointer, or NULL.
*/
virtual unsigned char* getRegisterPool();
/**
* get this dispatch's state.
* get the size of the register pool of this dispatch.
* @return the size.
*/
virtual int getRegisterPoolSize();
/**
* get this dispatch's state. DO NOT IMPLEMENT YET.
* @return a pointer to the dispatch's state. must be deallocated manually!
*/
virtual void* getState();
/**
* set this dispatch's state.
* set this dispatch's state. DO NOT IMPLEMENT YET.
* @param state a pointer to a state pertaining to this dispatch,
* or NULL if this dispatch does not support state saves.
*/

View file

@ -400,6 +400,7 @@ bool DivEngine::saveAudio(const char* path, int loops, DivAudioExportModes mode)
exportMode=mode;
exporting=true;
stop();
repeatPattern=false;
setOrder(0);
remainingLoops=loops;
exportThread=new std::thread(_runExportThread,this);
@ -548,9 +549,9 @@ void DivEngine::renderSamples() {
if (diff>=tempstep) encoded|=1;
acc+=jediTable[decstep+encoded];
if (acc>0x7ff || acc<-0x800) {
/*if (acc>0x7ff || acc<-0x800) {
logW("clipping! %d\n",acc);
}
}*/
acc&=0xfff;
if (acc&0x800) acc|=~0xfff;
decstep+=adStepSeek[encoded&7]*16;
@ -728,6 +729,13 @@ void* DivEngine::getDispatchChanState(int ch) {
return disCont[dispatchOfChan[ch]].dispatch->getChanState(dispatchChanOfChan[ch]);
}
unsigned char* DivEngine::getRegisterPool(int sys, int& size) {
if (sys<0 || sys>=song.systemLen) return NULL;
if (disCont[sys].dispatch==NULL) return NULL;
size=disCont[sys].dispatch->getRegisterPoolSize();
return disCont[sys].dispatch->getRegisterPool();
}
void DivEngine::enableCommandStream(bool enable) {
cmdStreamEnabled=enable;
}

View file

@ -37,8 +37,8 @@
warnings+=(String("\n")+x); \
}
#define DIV_VERSION "0.5.7pre4"
#define DIV_ENGINE_VERSION 52
#define DIV_VERSION "0.5.7"
#define DIV_ENGINE_VERSION 53
enum DivStatusView {
DIV_STATUS_NOTHING=0,
@ -529,6 +529,9 @@ class DivEngine {
// get dispatch channel state
void* getDispatchChanState(int chan);
// get register pool
unsigned char* getRegisterPool(int sys, int& size);
// enable command stream dumping
void enableCommandStream(bool enable);

View file

@ -135,6 +135,12 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
ds.brokenShortcutSlides=false;
ds.ignoreDuplicateSlides=true;
// 1.1 compat flags
if (ds.version>24) {
ds.waveDutyIsVol=true;
ds.legacyVolumeSlides=false;
}
// Neo Geo detune
if (ds.system[0]==DIV_SYSTEM_YM2610 || ds.system[0]==DIV_SYSTEM_YM2610_EXT) {
ds.tuning=443.23;

View file

@ -29,6 +29,14 @@ void* DivDispatch::getChanState(int chan) {
return NULL;
}
unsigned char* DivDispatch::getRegisterPool() {
return NULL;
}
int DivDispatch::getRegisterPoolSize() {
return 0;
}
void* DivDispatch::getState() {
return NULL;
}

View file

@ -145,6 +145,7 @@ void DivPlatformArcade::acquire_nuked(short* bufL, short* bufR, size_t start, si
QueuedWrite& w=writes.front();
if (w.addrOrVal) {
OPM_Write(&fm,1,w.val);
regPool[w.addr&0xff]=w.val;
//printf("write: %x = %.2x\n",w.addr,w.val);
writes.pop();
} else {
@ -216,6 +217,7 @@ void DivPlatformArcade::acquire_ymfm(short* bufL, short* bufR, size_t start, siz
QueuedWrite& w=writes.front();
fm_ymfm->write(0x0+((w.addr>>8)<<1),w.addr);
fm_ymfm->write(0x1+((w.addr>>8)<<1),w.val);
regPool[w.addr&0xff]=w.val;
writes.pop();
delay=1;
}
@ -877,6 +879,14 @@ void* DivPlatformArcade::getChanState(int ch) {
return &chan[ch];
}
unsigned char* DivPlatformArcade::getRegisterPool() {
return regPool;
}
int DivPlatformArcade::getRegisterPoolSize() {
return 256;
}
void DivPlatformArcade::poke(unsigned int addr, unsigned short val) {
immWrite(addr,val);
}
@ -887,6 +897,7 @@ void DivPlatformArcade::poke(std::vector<DivRegWrite>& wlist) {
void DivPlatformArcade::reset() {
while (!writes.empty()) writes.pop();
memset(regPool,0,256);
if (useYMFM) {
fm_ymfm->reset();
} else {

View file

@ -71,6 +71,8 @@ class DivPlatformArcade: public DivDispatch {
ymfm::ym2151::output_data out_ymfm;
DivArcadeInterface iface;
unsigned char regPool[256];
bool extMode, useYMFM;
bool isMuted[13];
@ -90,6 +92,8 @@ class DivPlatformArcade: public DivDispatch {
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();
void reset();
void forceIns();
void tick();

View file

@ -94,6 +94,7 @@ void DivPlatformAY8910::acquire(short* bufL, short* bufR, size_t start, size_t l
QueuedWrite w=writes.front();
ay->address_w(w.addr);
ay->data_w(w.val);
regPool[w.addr&0x0f]=w.val;
writes.pop();
}
ay->sound_stream_update(ayBuf,len);
@ -400,9 +401,18 @@ void* DivPlatformAY8910::getChanState(int ch) {
return &chan[ch];
}
unsigned char* DivPlatformAY8910::getRegisterPool() {
return regPool;
}
int DivPlatformAY8910::getRegisterPoolSize() {
return 16;
}
void DivPlatformAY8910::reset() {
while (!writes.empty()) writes.pop();
ay->device_reset();
memset(regPool,0,16);
for (int i=0; i<3; i++) {
chan[i]=DivPlatformAY8910::Channel();
chan[i].vol=0x0f;

View file

@ -47,6 +47,7 @@ class DivPlatformAY8910: public DivDispatch {
};
std::queue<QueuedWrite> writes;
ay8910_device* ay;
unsigned char regPool[16];
unsigned char lastBusy;
bool dacMode;
@ -76,6 +77,8 @@ class DivPlatformAY8910: public DivDispatch {
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();
void reset();
void forceIns();
void tick();

View file

@ -124,6 +124,7 @@ void DivPlatformAY8930::acquire(short* bufL, short* bufR, size_t start, size_t l
} else {
ay->data_w(w.val);
}
regPool[w.addr&0x1f]=w.val;
writes.pop();
}
ay->sound_stream_update(ayBuf,len);
@ -462,9 +463,18 @@ void* DivPlatformAY8930::getChanState(int ch) {
return &chan[ch];
}
unsigned char* DivPlatformAY8930::getRegisterPool() {
return regPool;
}
int DivPlatformAY8930::getRegisterPoolSize() {
return 32;
}
void DivPlatformAY8930::reset() {
while (!writes.empty()) writes.pop();
ay->device_reset();
memset(regPool,0,32);
for (int i=0; i<3; i++) {
chan[i]=DivPlatformAY8930::Channel();
chan[i].vol=31;

View file

@ -47,6 +47,7 @@ class DivPlatformAY8930: public DivDispatch {
};
std::queue<QueuedWrite> writes;
ay8930_device* ay;
unsigned char regPool[32];
unsigned char ayNoiseAnd, ayNoiseOr;
bool bank;
@ -69,6 +70,8 @@ class DivPlatformAY8930: public DivDispatch {
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();
void reset();
void forceIns();
void tick();

View file

@ -21,7 +21,7 @@
#include "../engine.h"
#include <math.h>
#define rWrite(a,v) if (!skipRegisterWrites) {sid.write(a,v); if (dumpWrites) {addWrite(a,v);} }
#define rWrite(a,v) if (!skipRegisterWrites) {sid.write(a,v); regPool[(a)&0x1f]=v; if (dumpWrites) {addWrite(a,v);} }
#define CHIP_FREQBASE 524288
@ -467,12 +467,21 @@ void* DivPlatformC64::getChanState(int ch) {
return &chan[ch];
}
unsigned char* DivPlatformC64::getRegisterPool() {
return regPool;
}
int DivPlatformC64::getRegisterPoolSize() {
return 32;
}
void DivPlatformC64::reset() {
for (int i=0; i<3; i++) {
chan[i]=DivPlatformC64::Channel();
}
sid.reset();
memset(regPool,0,32);
rWrite(0x18,0x0f);

View file

@ -70,6 +70,7 @@ class DivPlatformC64: public DivDispatch {
int filtCut, resetTime;
SID sid;
unsigned char regPool[32];
friend void putDispatchChan(void*,int,int);
@ -78,6 +79,8 @@ class DivPlatformC64: public DivDispatch {
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();
void reset();
void forceIns();
void tick();

View file

@ -21,8 +21,8 @@
#include "../engine.h"
#include <math.h>
#define rWrite(a,v) if (!skipRegisterWrites) {GB_apu_write(gb,a,v); if (dumpWrites) {addWrite(a,v);} }
#define immWrite(a,v) {GB_apu_write(gb,a,v); if (dumpWrites) {addWrite(a,v);} }
#define rWrite(a,v) if (!skipRegisterWrites) {GB_apu_write(gb,a,v); regPool[(a)&0x7f]=v; if (dumpWrites) {addWrite(a,v);} }
#define immWrite(a,v) {GB_apu_write(gb,a,v); regPool[(a)&0x7f]=v; if (dumpWrites) {addWrite(a,v);} }
#define CHIP_DIVIDER 16
@ -395,6 +395,14 @@ void* DivPlatformGB::getChanState(int ch) {
return &chan[ch];
}
unsigned char* DivPlatformGB::getRegisterPool() {
return regPool;
}
int DivPlatformGB::getRegisterPoolSize() {
return 64;
}
void DivPlatformGB::reset() {
for (int i=0; i<4; i++) {
chan[i]=DivPlatformGB::Channel();
@ -403,6 +411,7 @@ void DivPlatformGB::reset() {
addWrite(0xffffffff,0);
}
memset(gb,0,sizeof(GB_gameboy_t));
memset(regPool,0,128);
gb->model=GB_MODEL_DMG_B;
GB_apu_init(gb);
GB_set_sample_rate(gb,rate);

View file

@ -55,6 +55,8 @@ class DivPlatformGB: public DivDispatch {
unsigned char lastPan;
GB_gameboy_t* gb;
unsigned char regPool[128];
unsigned char procMute();
void updateWave();
friend void putDispatchChan(void*,int,int);
@ -62,6 +64,8 @@ class DivPlatformGB: public DivDispatch {
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();
void reset();
void forceIns();
void tick();

View file

@ -121,6 +121,7 @@ void DivPlatformGenesis::acquire_nuked(short* bufL, short* bufR, size_t start, s
OPN2_Write(&fm,0x1+((w.addr>>8)<<1),w.val);
//printf("write: %x = %.2x\n",w.addr,w.val);
lastBusy=0;
regPool[w.addr&0x1ff]=w.val;
writes.pop();
} else {
lastBusy++;
@ -190,6 +191,7 @@ void DivPlatformGenesis::acquire_ymfm(short* bufL, short* bufR, size_t start, si
QueuedWrite& w=writes.front();
fm_ymfm->write(0x0+((w.addr>>8)<<1),w.addr);
fm_ymfm->write(0x1+((w.addr>>8)<<1),w.val);
regPool[w.addr&0x1ff]=w.val;
writes.pop();
lastBusy=1;
}
@ -805,8 +807,17 @@ void* DivPlatformGenesis::getChanState(int ch) {
return &chan[ch];
}
unsigned char* DivPlatformGenesis::getRegisterPool() {
return regPool;
}
int DivPlatformGenesis::getRegisterPoolSize() {
return 512;
}
void DivPlatformGenesis::reset() {
while (!writes.empty()) writes.pop();
memset(regPool,0,512);
if (useYMFM) {
fm_ymfm->reset();
}

View file

@ -79,6 +79,7 @@ class DivPlatformGenesis: public DivDispatch {
ymfm::ym2612* fm_ymfm;
ymfm::ym2612::output_data out_ymfm;
DivYM2612Interface iface;
unsigned char regPool[512];
bool dacMode;
int dacPeriod;
@ -106,6 +107,8 @@ class DivPlatformGenesis: public DivDispatch {
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();
void reset();
void forceIns();
void tick();

View file

@ -25,7 +25,7 @@
#define CHIP_DIVIDER 16
#define rWrite(a,v) if (!skipRegisterWrites) {apu_wr_reg(nes,a,v); if (dumpWrites) {addWrite(a,v);} }
#define rWrite(a,v) if (!skipRegisterWrites) {apu_wr_reg(nes,a,v); regPool[(a)&0x7f]=v; if (dumpWrites) {addWrite(a,v);} }
const char* regCheatSheetNES[]={
"S0Volume", "4000",
@ -444,6 +444,14 @@ void* DivPlatformNES::getChanState(int ch) {
return &chan[ch];
}
unsigned char* DivPlatformNES::getRegisterPool() {
return regPool;
}
int DivPlatformNES::getRegisterPoolSize() {
return 32;
}
void DivPlatformNES::reset() {
for (int i=0; i<5; i++) {
chan[i]=DivPlatformNES::Channel();
@ -459,6 +467,7 @@ void DivPlatformNES::reset() {
sampleBank=0;
apu_turn_on(nes,apuType);
memset(regPool,0,128);
nes->apu.cpu_cycles=0;
nes->apu.cpu_opcode_cycle=0;

View file

@ -59,6 +59,7 @@ class DivPlatformNES: public DivDispatch {
unsigned char sampleBank;
unsigned char apuType;
struct NESAPU* nes;
unsigned char regPool[128];
friend void putDispatchChan(void*,int,int);
@ -66,6 +67,8 @@ class DivPlatformNES: public DivDispatch {
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();
void reset();
void forceIns();
void tick();

View file

@ -29,6 +29,7 @@
curChan=c; \
rWrite(0,curChan); \
} \
regPool[16+((c)<<4)+((a)&0x0f)]=v; \
rWrite(a,v); \
}
@ -88,11 +89,12 @@ void DivPlatformPCE::acquire(short* bufL, short* bufR, size_t start, size_t len)
chWrite(i,0x07,0);
if (s->depth==8) {
chWrite(i,0x04,0xdf);
chWrite(i,0x06,(((unsigned char)s->rendData[chan[i].dacPos++]+0x80)>>3));
chWrite(i,0x06,(((unsigned char)s->rendData[chan[i].dacPos]+0x80)>>3));
} else {
chWrite(i,0x04,0xdf);
chWrite(i,0x06,(((unsigned short)s->rendData[chan[i].dacPos++]+0x8000)>>11));
chWrite(i,0x06,(((unsigned short)s->rendData[chan[i].dacPos]+0x8000)>>11));
}
chan[i].dacPos++;
if (chan[i].dacPos>=s->rendLength) {
if (s->loopStart>=0 && s->loopStart<=(int)s->rendLength) {
chan[i].dacPos=s->loopStart;
@ -110,6 +112,7 @@ void DivPlatformPCE::acquire(short* bufL, short* bufR, size_t start, size_t len)
while (!writes.empty() && cycles<24) {
QueuedWrite w=writes.front();
pce->Write(cycles,w.addr,w.val);
regPool[w.addr&0x0f]=w.val;
//cycles+=2;
writes.pop();
}
@ -442,8 +445,17 @@ void* DivPlatformPCE::getChanState(int ch) {
return &chan[ch];
}
unsigned char* DivPlatformPCE::getRegisterPool() {
return regPool;
}
int DivPlatformPCE::getRegisterPoolSize() {
return 112;
}
void DivPlatformPCE::reset() {
while (!writes.empty()) writes.pop();
memset(regPool,0,128);
for (int i=0; i<6; i++) {
chan[i]=DivPlatformPCE::Channel();
}

View file

@ -74,12 +74,15 @@ class DivPlatformPCE: public DivDispatch {
int tempR[32];
unsigned char sampleBank, lfoMode, lfoSpeed;
PCE_PSG* pce;
unsigned char regPool[128];
void updateWave(int ch);
friend void putDispatchChan(void*,int,int);
public:
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();
void reset();
void forceIns();
void tick();

View file

@ -83,6 +83,7 @@ void DivPlatformSAA1099::acquire_mame(short* bufL, short* bufR, size_t start, si
QueuedWrite w=writes.front();
saa.control_w(w.addr);
saa.data_w(w.val);
regPool[w.addr&0x1f]=w.val;
writes.pop();
}
saa.sound_stream_update(saaBuf,len);
@ -103,6 +104,7 @@ void DivPlatformSAA1099::acquire_saaSound(short* bufL, short* bufR, size_t start
while (!writes.empty()) {
QueuedWrite w=writes.front();
saa_saaSound->WriteAddressData(w.addr,w.val);
regPool[w.addr&0x1f]=w.val;
writes.pop();
}
saa_saaSound->GenerateMany((unsigned char*)saaBuf[0],len);
@ -367,8 +369,17 @@ void* DivPlatformSAA1099::getChanState(int ch) {
return &chan[ch];
}
unsigned char* DivPlatformSAA1099::getRegisterPool() {
return regPool;
}
int DivPlatformSAA1099::getRegisterPoolSize() {
return 32;
}
void DivPlatformSAA1099::reset() {
while (!writes.empty()) writes.pop();
memset(regPool,0,32);
switch (core) {
case DIV_SAA_CORE_MAME:
saa=saa1099_device();

View file

@ -56,6 +56,7 @@ class DivPlatformSAA1099: public DivDispatch {
DivSAACores core;
saa1099_device saa;
CSAASound* saa_saaSound;
unsigned char regPool[32];
unsigned char lastBusy;
bool dacMode;
@ -85,6 +86,8 @@ class DivPlatformSAA1099: public DivDispatch {
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();
void reset();
void forceIns();
void tick();

View file

@ -22,7 +22,7 @@
#include <string.h>
#include <math.h>
#define rWrite(a,v) if (!skipRegisterWrites) {tia.set(a,v); if (dumpWrites) {addWrite(a,v);} }
#define rWrite(a,v) if (!skipRegisterWrites) {tia.set(a,v); regPool[((a)-0x15)&0x0f]=v; if (dumpWrites) {addWrite(a,v);} }
const char* regCheatSheetTIA[]={
"AUDC0", "15",
@ -281,8 +281,17 @@ void* DivPlatformTIA::getChanState(int ch) {
return &chan[ch];
}
unsigned char* DivPlatformTIA::getRegisterPool() {
return regPool;
}
int DivPlatformTIA::getRegisterPoolSize() {
return 6;
}
void DivPlatformTIA::reset() {
tia.reset();
memset(regPool,0,16);
for (int i=0; i<2; i++) {
chan[i]=DivPlatformTIA::Channel();
chan[i].vol=0x0f;

View file

@ -38,6 +38,7 @@ class DivPlatformTIA: public DivDispatch {
Channel chan[2];
bool isMuted[2];
TIASound tia;
unsigned char regPool[16];
friend void putDispatchChan(void*,int,int);
unsigned char dealWithFreq(unsigned char shape, int base, int pitch);
@ -46,6 +47,8 @@ class DivPlatformTIA: public DivDispatch {
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();
void reset();
void forceIns();
void tick();

View file

@ -111,6 +111,7 @@ void DivPlatformYM2610::acquire(short* bufL, short* bufR, size_t start, size_t l
QueuedWrite& w=writes.front();
fm->write(0x0+((w.addr>>8)<<1),w.addr);
fm->write(0x1+((w.addr>>8)<<1),w.val);
regPool[w.addr&0x1ff]=w.val;
writes.pop();
delay=4;
}
@ -848,6 +849,14 @@ void* DivPlatformYM2610::getChanState(int ch) {
return &chan[ch];
}
unsigned char* DivPlatformYM2610::getRegisterPool() {
return regPool;
}
int DivPlatformYM2610::getRegisterPoolSize() {
return 512;
}
void DivPlatformYM2610::poke(unsigned int addr, unsigned short val) {
immWrite(addr,val);
}
@ -858,6 +867,7 @@ void DivPlatformYM2610::poke(std::vector<DivRegWrite>& wlist) {
void DivPlatformYM2610::reset() {
while (!writes.empty()) writes.pop();
memset(regPool,0,512);
if (dumpWrites) {
addWrite(0xffffffff,0);
}

View file

@ -59,6 +59,7 @@ class DivPlatformYM2610: public DivDispatch {
ymfm::ym2610* fm;
ymfm::ym2610::output_data fmout;
DivYM2610Interface iface;
unsigned char regPool[512];
unsigned char lastBusy;
bool dacMode;
@ -88,6 +89,8 @@ class DivPlatformYM2610: public DivDispatch {
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();
void reset();
void forceIns();
void tick();

View file

@ -403,6 +403,7 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop) {
stop();
repeatPattern=false;
setOrder(0);
isBusy.lock();
double origRate=got.rate;