mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-05 20:35:06 +00:00
Merge branch 'master' of https://github.com/tildearrow/furnace into sample_macro
This commit is contained in:
commit
d82d7255d1
17 changed files with 199 additions and 56 deletions
|
@ -36,12 +36,20 @@
|
|||
#define CONFIG_FILE "/furnace.cfg"
|
||||
#endif
|
||||
|
||||
#ifdef IS_MOBILE
|
||||
#ifdef HAVE_SDL2
|
||||
#include <SDL.h>
|
||||
#else
|
||||
#error "Furnace mobile requires SDL2!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void DivEngine::initConfDir() {
|
||||
#ifdef _WIN32
|
||||
// maybe move this function in here instead?
|
||||
configPath=getWinConfigPath();
|
||||
#elif defined (IS_MOBILE)
|
||||
configPath=SDL_GetPrefPath();
|
||||
#elif defined(IS_MOBILE)
|
||||
configPath=SDL_GetPrefPath("tildearrow","furnace");
|
||||
#else
|
||||
#ifdef __HAIKU__
|
||||
char userSettingsDir[PATH_MAX];
|
||||
|
|
|
@ -218,10 +218,12 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
|
|||
break;
|
||||
case DIV_SYSTEM_C64_6581:
|
||||
dispatch=new DivPlatformC64;
|
||||
((DivPlatformC64*)dispatch)->setFP(eng->getConfInt("c64Core",1)==1);
|
||||
((DivPlatformC64*)dispatch)->setChipModel(true);
|
||||
break;
|
||||
case DIV_SYSTEM_C64_8580:
|
||||
dispatch=new DivPlatformC64;
|
||||
((DivPlatformC64*)dispatch)->setFP(eng->getConfInt("c64Core",1)==1);
|
||||
((DivPlatformC64*)dispatch)->setChipModel(false);
|
||||
break;
|
||||
case DIV_SYSTEM_YM2151:
|
||||
|
|
|
@ -1141,7 +1141,7 @@ void DivEngine::swapChannels(int src, int dest) {
|
|||
String prevChanName=curSubSong->chanName[src];
|
||||
String prevChanShortName=curSubSong->chanShortName[src];
|
||||
bool prevChanShow=curSubSong->chanShow[src];
|
||||
bool prevChanCollapse=curSubSong->chanCollapse[src];
|
||||
unsigned char prevChanCollapse=curSubSong->chanCollapse[src];
|
||||
|
||||
curSubSong->chanName[src]=curSubSong->chanName[dest];
|
||||
curSubSong->chanShortName[src]=curSubSong->chanShortName[dest];
|
||||
|
@ -1446,25 +1446,44 @@ bool DivEngine::swapSystem(int src, int dest, bool preserveOrder) {
|
|||
}
|
||||
}
|
||||
|
||||
// swap channels
|
||||
logV("swap list:");
|
||||
for (int i=0; i<tchans; i++) {
|
||||
logV("- %d -> %d",unswappedChannels[i],swappedChannels[i]);
|
||||
}
|
||||
|
||||
// swap channels
|
||||
bool allComplete=false;
|
||||
while (!allComplete) {
|
||||
logD("doing swap...");
|
||||
allComplete=true;
|
||||
for (int i=0; i<tchans; i++) {
|
||||
if (unswappedChannels[i]!=swappedChannels[i]) {
|
||||
swapChannels(i,swappedChannels[i]);
|
||||
allComplete=false;
|
||||
logD("> %d -> %d",unswappedChannels[i],unswappedChannels[swappedChannels[i]]);
|
||||
unswappedChannels[i]^=unswappedChannels[swappedChannels[i]];
|
||||
unswappedChannels[swappedChannels[i]]^=unswappedChannels[i];
|
||||
unswappedChannels[i]^=unswappedChannels[swappedChannels[i]];
|
||||
for (size_t i=0; i<song.subsong.size(); i++) {
|
||||
DivOrders prevOrders=song.subsong[i]->orders;
|
||||
DivPattern* prevPat[DIV_MAX_CHANS][256];
|
||||
unsigned char prevEffectCols[DIV_MAX_CHANS];
|
||||
String prevChanName[DIV_MAX_CHANS];
|
||||
String prevChanShortName[DIV_MAX_CHANS];
|
||||
bool prevChanShow[DIV_MAX_CHANS];
|
||||
unsigned char prevChanCollapse[DIV_MAX_CHANS];
|
||||
|
||||
for (int j=0; j<tchans; j++) {
|
||||
for (int k=0; k<256; k++) {
|
||||
prevPat[j][k]=song.subsong[i]->pat[j].data[k];
|
||||
}
|
||||
prevEffectCols[j]=song.subsong[i]->pat[j].effectCols;
|
||||
|
||||
prevChanName[j]=song.subsong[i]->chanName[j];
|
||||
prevChanShortName[j]=song.subsong[i]->chanShortName[j];
|
||||
prevChanShow[j]=song.subsong[i]->chanShow[j];
|
||||
prevChanCollapse[j]=song.subsong[i]->chanCollapse[j];
|
||||
}
|
||||
|
||||
for (int j=0; j<tchans; j++) {
|
||||
for (int k=0; k<256; k++) {
|
||||
song.subsong[i]->orders.ord[j][k]=prevOrders.ord[swappedChannels[j]][k];
|
||||
song.subsong[i]->pat[j].data[k]=prevPat[swappedChannels[j]][k];
|
||||
}
|
||||
|
||||
song.subsong[i]->pat[j].effectCols=prevEffectCols[swappedChannels[j]];
|
||||
song.subsong[i]->chanName[j]=prevChanName[swappedChannels[j]];
|
||||
song.subsong[i]->chanShortName[j]=prevChanShortName[swappedChannels[j]];
|
||||
song.subsong[i]->chanShow[j]=prevChanShow[swappedChannels[j]];
|
||||
song.subsong[i]->chanCollapse[j]=prevChanCollapse[swappedChannels[j]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1648,7 +1667,7 @@ void DivEngine::playSub(bool preserveDrift, int goalRow) {
|
|||
}
|
||||
}
|
||||
int oldOrder=curOrder;
|
||||
while (playing && curRow<goalRow) {
|
||||
while (playing && (curRow<goalRow || ticks>1)) {
|
||||
if (nextTick(preserveDrift)) {
|
||||
skipping=false;
|
||||
return;
|
||||
|
|
|
@ -4346,14 +4346,25 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) {
|
|||
}
|
||||
}
|
||||
|
||||
bool relWarning=false;
|
||||
|
||||
for (int i=0; i<getChannelCount(sys); i++) {
|
||||
w->writeC(curPat[i].effectCols);
|
||||
|
||||
for (int j=0; j<curSubSong->ordersLen; j++) {
|
||||
DivPattern* pat=curPat[i].getPattern(curOrders->ord[i][j],false);
|
||||
for (int k=0; k<curSubSong->patLen; k++) {
|
||||
w->writeS(pat->data[k][0]); // note
|
||||
w->writeS(pat->data[k][1]); // octave
|
||||
if ((pat->data[k][0]==101 || pat->data[k][0]==102) && pat->data[k][1]==0) {
|
||||
w->writeS(100);
|
||||
w->writeS(0);
|
||||
if (!relWarning) {
|
||||
relWarning=true;
|
||||
addWarning("note/macro release will be converted to note off!");
|
||||
}
|
||||
} else {
|
||||
w->writeS(pat->data[k][0]); // note
|
||||
w->writeS(pat->data[k][1]); // octave
|
||||
}
|
||||
w->writeS(pat->data[k][3]); // volume
|
||||
#ifdef TA_BIG_ENDIAN
|
||||
for (int l=0; l<curPat[i].effectCols*2; l++) {
|
||||
|
|
|
@ -50,7 +50,7 @@ struct DivMacroStruct {
|
|||
finished(false),
|
||||
will(false),
|
||||
linger(false),
|
||||
began(false),
|
||||
began(true),
|
||||
mode(0) {}
|
||||
};
|
||||
|
||||
|
|
|
@ -69,6 +69,14 @@ const char* regCheatSheetAY8914[]={
|
|||
NULL
|
||||
};
|
||||
|
||||
// taken from ay8910.cpp
|
||||
const int sunsoftVolTable[32]={
|
||||
103350, 73770, 52657, 37586, 32125, 27458, 24269, 21451,
|
||||
18447, 15864, 14009, 12371, 10506, 8922, 7787, 6796,
|
||||
5689, 4763, 4095, 3521, 2909, 2403, 2043, 1737,
|
||||
1397, 1123, 925, 762, 578, 438, 332, 251
|
||||
};
|
||||
|
||||
const char** DivPlatformAY8910::getRegisterSheet() {
|
||||
return intellivision?regCheatSheetAY8914:regCheatSheetAY;
|
||||
}
|
||||
|
@ -134,27 +142,33 @@ void DivPlatformAY8910::acquire(short* bufL, short* bufR, size_t start, size_t l
|
|||
regPool[w.addr&0x0f]=w.val;
|
||||
writes.pop();
|
||||
}
|
||||
ay->sound_stream_update(ayBuf,len);
|
||||
if (sunsoft) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
bufL[i+start]=ayBuf[0][i];
|
||||
ay->sound_stream_update(ayBuf,1);
|
||||
bufL[i+start]=ayBuf[0][0];
|
||||
bufR[i+start]=bufL[i+start];
|
||||
}
|
||||
} else if (stereo) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
bufL[i+start]=ayBuf[0][i]+ayBuf[1][i];
|
||||
bufR[i+start]=ayBuf[1][i]+ayBuf[2][i];
|
||||
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=sunsoftVolTable[31-(ay->lastIndx&31)]>>3;
|
||||
oscBuf[1]->data[oscBuf[1]->needle++]=sunsoftVolTable[31-((ay->lastIndx>>5)&31)]>>3;
|
||||
oscBuf[2]->data[oscBuf[2]->needle++]=sunsoftVolTable[31-((ay->lastIndx>>10)&31)]>>3;
|
||||
}
|
||||
} else {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
bufL[i+start]=ayBuf[0][i]+ayBuf[1][i]+ayBuf[2][i];
|
||||
bufR[i+start]=bufL[i+start];
|
||||
ay->sound_stream_update(ayBuf,len);
|
||||
if (stereo) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
bufL[i+start]=ayBuf[0][i]+ayBuf[1][i];
|
||||
bufR[i+start]=ayBuf[1][i]+ayBuf[2][i];
|
||||
}
|
||||
} else {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
bufL[i+start]=ayBuf[0][i]+ayBuf[1][i]+ayBuf[2][i];
|
||||
bufR[i+start]=bufL[i+start];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int ch=0; ch<3; ch++) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
oscBuf[ch]->data[oscBuf[ch]->needle++]=ayBuf[ch][i];
|
||||
for (int ch=0; ch<3; ch++) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
oscBuf[ch]->data[oscBuf[ch]->needle++]=ayBuf[ch][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,9 +19,10 @@
|
|||
|
||||
#include "c64.h"
|
||||
#include "../engine.h"
|
||||
#include "sound/c64_fp/siddefs-fp.h"
|
||||
#include <math.h>
|
||||
|
||||
#define rWrite(a,v) if (!skipRegisterWrites) {sid.write(a,v); regPool[(a)&0x1f]=v; if (dumpWrites) {addWrite(a,v);} }
|
||||
#define rWrite(a,v) if (!skipRegisterWrites) {if (isFP) {sid_fp.write(a,v);} else {sid.write(a,v);}; regPool[(a)&0x1f]=v; if (dumpWrites) {addWrite(a,v);} }
|
||||
|
||||
#define CHIP_FREQBASE 524288
|
||||
|
||||
|
@ -63,15 +64,25 @@ const char** DivPlatformC64::getRegisterSheet() {
|
|||
}
|
||||
|
||||
void DivPlatformC64::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
int dcOff=sid.get_dc(0);
|
||||
int dcOff=isFP?0:sid.get_dc(0);
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
sid.clock();
|
||||
bufL[i]=sid.output();
|
||||
if (++writeOscBuf>=8) {
|
||||
writeOscBuf=0;
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=(sid.last_chan_out[0]-dcOff)>>5;
|
||||
oscBuf[1]->data[oscBuf[1]->needle++]=(sid.last_chan_out[1]-dcOff)>>5;
|
||||
oscBuf[2]->data[oscBuf[2]->needle++]=(sid.last_chan_out[2]-dcOff)>>5;
|
||||
if (isFP) {
|
||||
sid_fp.clock(4,&bufL[i]);
|
||||
if (++writeOscBuf>=4) {
|
||||
writeOscBuf=0;
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=(sid_fp.lastChanOut[0]-dcOff)>>5;
|
||||
oscBuf[1]->data[oscBuf[1]->needle++]=(sid_fp.lastChanOut[1]-dcOff)>>5;
|
||||
oscBuf[2]->data[oscBuf[2]->needle++]=(sid_fp.lastChanOut[2]-dcOff)>>5;
|
||||
}
|
||||
} else {
|
||||
sid.clock();
|
||||
bufL[i]=sid.output();
|
||||
if (++writeOscBuf>=16) {
|
||||
writeOscBuf=0;
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=(sid.last_chan_out[0]-dcOff)>>5;
|
||||
oscBuf[1]->data[oscBuf[1]->needle++]=(sid.last_chan_out[1]-dcOff)>>5;
|
||||
oscBuf[2]->data[oscBuf[2]->needle++]=(sid.last_chan_out[2]-dcOff)>>5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -405,7 +416,11 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
|||
|
||||
void DivPlatformC64::muteChannel(int ch, bool mute) {
|
||||
isMuted[ch]=mute;
|
||||
sid.set_is_muted(ch,mute);
|
||||
if (isFP) {
|
||||
sid_fp.mute(ch,mute);
|
||||
} else {
|
||||
sid.set_is_muted(ch,mute);
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformC64::forceIns() {
|
||||
|
@ -462,13 +477,21 @@ bool DivPlatformC64::getWantPreNote() {
|
|||
return true;
|
||||
}
|
||||
|
||||
float DivPlatformC64::getPostAmp() {
|
||||
return isFP?3.0f:1.0f;
|
||||
}
|
||||
|
||||
void DivPlatformC64::reset() {
|
||||
for (int i=0; i<3; i++) {
|
||||
chan[i]=DivPlatformC64::Channel();
|
||||
chan[i].std.setEngine(parent);
|
||||
}
|
||||
|
||||
sid.reset();
|
||||
if (isFP) {
|
||||
sid_fp.reset();
|
||||
} else {
|
||||
sid.reset();
|
||||
}
|
||||
memset(regPool,0,32);
|
||||
|
||||
rWrite(0x18,0x0f);
|
||||
|
@ -490,12 +513,24 @@ void DivPlatformC64::poke(std::vector<DivRegWrite>& wlist) {
|
|||
|
||||
void DivPlatformC64::setChipModel(bool is6581) {
|
||||
if (is6581) {
|
||||
sid.set_chip_model(MOS6581);
|
||||
if (isFP) {
|
||||
sid_fp.setChipModel(reSIDfp::MOS6581);
|
||||
} else {
|
||||
sid.set_chip_model(MOS6581);
|
||||
}
|
||||
} else {
|
||||
sid.set_chip_model(MOS8580);
|
||||
if (isFP) {
|
||||
sid_fp.setChipModel(reSIDfp::MOS8580);
|
||||
} else {
|
||||
sid.set_chip_model(MOS8580);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformC64::setFP(bool fp) {
|
||||
isFP=fp;
|
||||
}
|
||||
|
||||
void DivPlatformC64::setFlags(unsigned int flags) {
|
||||
switch (flags&0xf) {
|
||||
case 0x0: // NTSC C64
|
||||
|
@ -513,6 +548,10 @@ void DivPlatformC64::setFlags(unsigned int flags) {
|
|||
for (int i=0; i<3; i++) {
|
||||
oscBuf[i]->rate=rate/16;
|
||||
}
|
||||
if (isFP) {
|
||||
rate/=4;
|
||||
sid_fp.setSamplingParameters(chipClock,reSIDfp::DECIMATE,rate,0);
|
||||
}
|
||||
}
|
||||
|
||||
int DivPlatformC64::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "../dispatch.h"
|
||||
#include "../macroInt.h"
|
||||
#include "sound/c64/sid.h"
|
||||
#include "sound/c64_fp/SID.h"
|
||||
|
||||
class DivPlatformC64: public DivDispatch {
|
||||
struct Channel {
|
||||
|
@ -76,12 +77,17 @@ class DivPlatformC64: public DivDispatch {
|
|||
unsigned char filtControl, filtRes, vol;
|
||||
unsigned char writeOscBuf;
|
||||
int filtCut, resetTime;
|
||||
bool isFP;
|
||||
|
||||
SID sid;
|
||||
reSIDfp::SID sid_fp;
|
||||
unsigned char regPool[32];
|
||||
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
void acquire_classic(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_fp(short* bufL, short* bufR, size_t start, size_t len);
|
||||
|
||||
void updateFilter();
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
|
@ -98,6 +104,7 @@ class DivPlatformC64: public DivDispatch {
|
|||
void notifyInsChange(int ins);
|
||||
bool getDCOffRequired();
|
||||
bool getWantPreNote();
|
||||
float getPostAmp();
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
void notifyInsDeletion(void* ins);
|
||||
void poke(unsigned int addr, unsigned short val);
|
||||
|
@ -105,6 +112,7 @@ class DivPlatformC64: public DivDispatch {
|
|||
const char** getRegisterSheet();
|
||||
int init(DivEngine* parent, int channels, int sugRate, unsigned int flags);
|
||||
void setChipModel(bool is6581);
|
||||
void setFP(bool fp);
|
||||
void quit();
|
||||
~DivPlatformC64();
|
||||
};
|
||||
|
|
|
@ -115,11 +115,11 @@ void DivPlatformNES::acquire_puNES(short* bufL, short* bufR, size_t start, size_
|
|||
bufL[i]=sample;
|
||||
if (++writeOscBuf>=32) {
|
||||
writeOscBuf=0;
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=nes->S1.output<<11;
|
||||
oscBuf[1]->data[oscBuf[1]->needle++]=nes->S2.output<<11;
|
||||
oscBuf[2]->data[oscBuf[2]->needle++]=nes->TR.output<<11;
|
||||
oscBuf[3]->data[oscBuf[3]->needle++]=nes->NS.output<<11;
|
||||
oscBuf[4]->data[oscBuf[4]->needle++]=nes->DMC.output<<8;
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=isMuted[0]?0:(nes->S1.output<<11);
|
||||
oscBuf[1]->data[oscBuf[1]->needle++]=isMuted[1]?0:(nes->S2.output<<11);
|
||||
oscBuf[2]->data[oscBuf[2]->needle++]=isMuted[2]?0:(nes->TR.output<<11);
|
||||
oscBuf[3]->data[oscBuf[3]->needle++]=isMuted[3]?0:(nes->NS.output<<11);
|
||||
oscBuf[4]->data[oscBuf[4]->needle++]=isMuted[4]?0:(nes->DMC.output<<8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -924,6 +924,7 @@ float ay8910_device::mix_3D()
|
|||
indx |= tone_mask | (m_vol_enabled[chan] ? tone_volume(tone) << (chan*5) : 0);
|
||||
}
|
||||
}
|
||||
lastIndx=indx;
|
||||
return m_vol3d_table[indx];
|
||||
}
|
||||
|
||||
|
@ -1359,6 +1360,7 @@ unsigned char ay8910_device::ay8910_read_ym()
|
|||
|
||||
void ay8910_device::device_reset()
|
||||
{
|
||||
lastIndx=0;
|
||||
ay8910_reset_ym();
|
||||
}
|
||||
|
||||
|
|
|
@ -146,6 +146,8 @@ public:
|
|||
double m_Kn[32];
|
||||
};
|
||||
|
||||
int lastIndx;
|
||||
|
||||
// internal interface for PSG component of YM device
|
||||
// FIXME: these should be private, but vector06 accesses them directly
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ private:
|
|||
*
|
||||
* @return the output sample
|
||||
*/
|
||||
int output() const;
|
||||
int output();
|
||||
|
||||
/**
|
||||
* Calculate the numebr of cycles according to current parameters
|
||||
|
@ -146,6 +146,8 @@ public:
|
|||
SID();
|
||||
~SID();
|
||||
|
||||
int lastChanOut[3];
|
||||
|
||||
/**
|
||||
* Set chip model.
|
||||
*
|
||||
|
@ -312,12 +314,16 @@ void SID::ageBusValue(unsigned int n)
|
|||
}
|
||||
|
||||
RESID_INLINE
|
||||
int SID::output() const
|
||||
int SID::output()
|
||||
{
|
||||
const int v1 = voice[0]->output(voice[2]->wave());
|
||||
const int v2 = voice[1]->output(voice[0]->wave());
|
||||
const int v3 = voice[2]->output(voice[1]->wave());
|
||||
|
||||
lastChanOut[0]=v1;
|
||||
lastChanOut[1]=v2;
|
||||
lastChanOut[2]=v3;
|
||||
|
||||
return externalFilter->clock(filter->clock(v1, v2, v3));
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,8 @@ void DivPlatformSwan::acquire(short* bufL, short* bufR, size_t start, size_t len
|
|||
DivSample* s=parent->getSample(dacSample);
|
||||
if (s->samples<=0) {
|
||||
dacSample=-1;
|
||||
continue;
|
||||
dacPeriod=0;
|
||||
break;
|
||||
}
|
||||
rWrite(0x09,(unsigned char)s->data8[dacPos++]+0x80);
|
||||
if (s->isLoopable() && dacPos>=(unsigned int)s->loopEnd) {
|
||||
|
|
|
@ -1298,6 +1298,32 @@ void FurnaceGUI::doAction(int what) {
|
|||
MARK_MODIFIED;
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_CREATE_WAVE: {
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
DivSample* sample=e->song.sample[curSample];
|
||||
SAMPLE_OP_BEGIN;
|
||||
if (end-start<1) {
|
||||
showError("select at least one sample!");
|
||||
} else if (end-start>256) {
|
||||
showError("maximum size is 256 samples!");
|
||||
} else {
|
||||
curWave=e->addWave();
|
||||
if (curWave==-1) {
|
||||
showError("too many wavetables!");
|
||||
} else {
|
||||
DivWavetable* wave=e->song.wave[curWave];
|
||||
wave->min=0;
|
||||
wave->max=255;
|
||||
wave->len=end-start;
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
wave->data[i-start]=(sample->data8[i]&0xff)^0x80;
|
||||
}
|
||||
nextWindow=GUI_WINDOW_WAVE_EDIT;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GUI_ACTION_ORDERS_UP:
|
||||
if (curOrder>0) {
|
||||
|
|
|
@ -533,6 +533,7 @@ enum FurnaceGUIActions {
|
|||
GUI_ACTION_SAMPLE_ZOOM_AUTO,
|
||||
GUI_ACTION_SAMPLE_MAKE_INS,
|
||||
GUI_ACTION_SAMPLE_SET_LOOP,
|
||||
GUI_ACTION_SAMPLE_CREATE_WAVE,
|
||||
GUI_ACTION_SAMPLE_MAX,
|
||||
|
||||
GUI_ACTION_ORDERS_MIN,
|
||||
|
|
|
@ -655,6 +655,7 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={
|
|||
D("SAMPLE_ZOOM_AUTO", "Toggle auto-zoom", FURKMOD_CMD|SDLK_0),
|
||||
D("SAMPLE_MAKE_INS", "Create instrument from sample", 0),
|
||||
D("SAMPLE_SET_LOOP", "Set loop to selection", FURKMOD_CMD|SDLK_l),
|
||||
D("SAMPLE_CREATE_WAVE", "Create wavetable from selection", FURKMOD_CMD|SDLK_w),
|
||||
D("SAMPLE_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("ORDERS_MIN", "---Orders", NOT_AN_ACTION),
|
||||
|
|
|
@ -1338,6 +1338,9 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
if (ImGui::MenuItem("set loop to selection",BIND_FOR(GUI_ACTION_SAMPLE_SET_LOOP))) {
|
||||
doAction(GUI_ACTION_SAMPLE_SET_LOOP);
|
||||
}
|
||||
if (ImGui::MenuItem("create wavetable from selection",BIND_FOR(GUI_ACTION_SAMPLE_CREATE_WAVE))) {
|
||||
doAction(GUI_ACTION_SAMPLE_CREATE_WAVE);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue