diff --git a/CMakeLists.txt b/CMakeLists.txt index 162618ebe..b18114ea7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,8 +4,8 @@ project(furnace) set(CMAKE_CXX_STANDARD 14) set(CMAKE_PROJECT_VERSION_MAJOR 0) -set(CMAKE_PROJECT_VERSION_MINOR 4) -set(CMAKE_PROJECT_VERSION_PATCH 6) +set(CMAKE_PROJECT_VERSION_MINOR 5) +set(CMAKE_PROJECT_VERSION_PATCH 0) if (ANDROID) set(BUILD_GUI OFF) diff --git a/res/Info.plist b/res/Info.plist index 621a4df23..f6db613d5 100644 --- a/res/Info.plist +++ b/res/Info.plist @@ -15,17 +15,17 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - 0.4.6 + 0.5 CFBundleName Furnace CFBundlePackageType APPL CFBundleShortVersionString - 0.4.6 + 0.5 CFBundleSignature ???? CFBundleVersion - 0.4.6 + 0.5 NSHumanReadableCopyright NSHighResolutionCapable diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index d8bbaf039..6c6714c7c 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -2287,25 +2287,40 @@ SafeWriter* DivEngine::saveVGM() { if (memPos>=16777216) break; sample->rendOffP=memPos; unsigned int alignedSize=(sample->rendLength+0xff)&(~0xff); + unsigned int readPos=0; if (alignedSize>65536) alignedSize=65536; if (sample->depth==8) { for (unsigned int j=0; j=sample->rendLength) { - pcmMem[memPos++]=0x80; + if (readPos>=sample->rendLength) { + if (sample->loopStart>=0 && sample->loopStart<(int)sample->rendLength) { + readPos=sample->loopStart; + pcmMem[memPos++]=((unsigned char)sample->rendData[readPos]+0x80); + } else { + pcmMem[memPos++]=0x80; + } } else { - pcmMem[memPos++]=((unsigned char)sample->rendData[j]+0x80); + pcmMem[memPos++]=((unsigned char)sample->rendData[readPos]+0x80); } + readPos++; if (memPos>=16777216) break; } + sample->loopOffP=readPos-sample->loopStart; } else { for (unsigned int j=0; j=sample->rendLength) { - pcmMem[memPos++]=0x80; + if (readPos>=sample->rendLength) { + if (sample->loopStart>=0 && sample->loopStart<(int)sample->rendLength) { + readPos=sample->loopStart; + pcmMem[memPos++]=(((unsigned short)sample->rendData[readPos]+0x8000)>>8); + } else { + pcmMem[memPos++]=0x80; + } } else { - pcmMem[memPos++]=(((unsigned short)sample->rendData[j]+0x8000)>>8); + pcmMem[memPos++]=(((unsigned short)sample->rendData[readPos]+0x8000)>>8); } + readPos++; if (memPos>=16777216) break; } + sample->loopOffP=readPos-sample->loopStart; } if (memPos>=16777216) break; } @@ -3896,6 +3911,7 @@ bool DivEngine::moveSampleDown(int which) { } void DivEngine::noteOn(int chan, int ins, int note, int vol) { + if (chan<0 || chan>=chans) return; isBusy.lock(); pendingNotes.push(DivNoteEvent(chan,ins,note,vol,true)); if (!playing) { @@ -3907,6 +3923,7 @@ void DivEngine::noteOn(int chan, int ins, int note, int vol) { } void DivEngine::noteOff(int chan) { + if (chan<0 || chan>=chans) return; isBusy.lock(); pendingNotes.push(DivNoteEvent(chan,-1,-1,-1,false)); if (!playing) { diff --git a/src/engine/engine.h b/src/engine/engine.h index ccd72f775..220bbf442 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -11,8 +11,8 @@ #include #include -#define DIV_VERSION "0.4.7pre1" -#define DIV_ENGINE_VERSION 29 +#define DIV_VERSION "0.5pre1" +#define DIV_ENGINE_VERSION 30 enum DivStatusView { DIV_STATUS_NOTHING=0, diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index a5291c125..28246ef4d 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -77,8 +77,7 @@ void DivPlatformArcade::acquire_nuked(short* bufL, short* bufR, size_t start, si chan[i].pcm.pos+=chan[i].pcm.freq; if (chan[i].pcm.pos>=(s->rendLength<<8)) { if (s->loopStart>=0 && s->loopStart<=(int)s->rendLength) { - // Sega PCM limitation - chan[i].pcm.pos=(s->loopStart&(~0xff))<<8; + chan[i].pcm.pos=s->loopStart<<8; } else { chan[i].pcm.sample=-1; } @@ -143,8 +142,7 @@ void DivPlatformArcade::acquire_ymfm(short* bufL, short* bufR, size_t start, siz chan[i].pcm.pos+=chan[i].pcm.freq; if (chan[i].pcm.pos>=(s->rendLength<<8)) { if (s->loopStart>=0 && s->loopStart<=(int)s->rendLength) { - // Sega PCM limitation - chan[i].pcm.pos=(s->loopStart&(~0xff))<<8; + chan[i].pcm.pos=s->loopStart<<8; } else { chan[i].pcm.sample=-1; } @@ -262,7 +260,14 @@ int DivPlatformArcade::dispatch(DivCommand c) { addWrite(0x10084+(pcmChan<<3),(s->rendOffP)&0xff); addWrite(0x10085+(pcmChan<<3),(s->rendOffP>>8)&0xff); addWrite(0x10006+(pcmChan<<3),MIN(255,((s->rendOffP&0xffff)+s->rendLength)>>8)); - addWrite(0x10086+(pcmChan<<3),2+((s->rendOffP>>16)<<3)); + if (s->loopStart<0 || s->loopStart>=(int)s->rendLength) { + addWrite(0x10086+(pcmChan<<3),2+((s->rendOffP>>16)<<3)); + } else { + int loopPos=(s->rendOffP&0xffff)+s->loopStart+s->loopOffP; + addWrite(0x10004+(pcmChan<<3),loopPos&0xff); + addWrite(0x10005+(pcmChan<<3),(loopPos>>8)&0xff); + addWrite(0x10086+(pcmChan<<3),((s->rendOffP>>16)<<3)); + } } } else { chan[c.chan].pcm.sample=12*sampleBank+c.value%12; @@ -282,7 +287,14 @@ int DivPlatformArcade::dispatch(DivCommand c) { addWrite(0x10084+(pcmChan<<3),(s->rendOffP)&0xff); addWrite(0x10085+(pcmChan<<3),(s->rendOffP>>8)&0xff); addWrite(0x10006+(pcmChan<<3),MIN(255,((s->rendOffP&0xffff)+s->rendLength)>>8)); - addWrite(0x10086+(pcmChan<<3),2+((s->rendOffP>>16)<<3)); + if (s->loopStart<0 || s->loopStart>=(int)s->rendLength) { + addWrite(0x10086+(pcmChan<<3),2+((s->rendOffP>>16)<<3)); + } else { + int loopPos=(s->rendOffP&0xffff)+s->loopStart+s->loopOffP; + addWrite(0x10004+(pcmChan<<3),loopPos&0xff); + addWrite(0x10005+(pcmChan<<3),(loopPos>>8)&0xff); + addWrite(0x10086+(pcmChan<<3),((s->rendOffP>>16)<<3)); + } addWrite(0x10007+(pcmChan<<3),chan[c.chan].pcm.freq); } } diff --git a/src/engine/sample.h b/src/engine/sample.h index 035385575..041a8359f 100644 --- a/src/engine/sample.h +++ b/src/engine/sample.h @@ -2,7 +2,7 @@ struct DivSample { String name; - int length, rate, loopStart; + int length, rate, loopStart, loopOffP; signed char vol, pitch; unsigned char depth; short* data; @@ -16,6 +16,7 @@ struct DivSample { length(0), rate(32000), loopStart(-1), + loopOffP(0), vol(0), pitch(0), depth(16),