diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 0f6d672d2..41d9808f9 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -707,19 +707,19 @@ bool DivEngine::load(void* f, size_t slen) { logI("reading patterns (%d channels, %d orders)...\n",getChannelCount(ds.system),ds.ordersLen); for (int i=0; ieffectRows=1; + chan.effectRows=1; } else { - chan->effectRows=reader.readC(); + chan.effectRows=reader.readC(); } - logD("%d fx rows: %d\n",i,chan->effectRows); - if (chan->effectRows>4 || chan->effectRows<1) { - logE("invalid effect row count %d. are you sure everything is ok?\n",chan->effectRows); + logD("%d fx rows: %d\n",i,chan.effectRows); + if (chan.effectRows>4 || chan.effectRows<1) { + logE("invalid effect row count %d. are you sure everything is ok?\n",chan.effectRows); return false; } for (int j=0; jgetPattern(ds.orders.ord[i][j],true); + DivPattern* pat=chan.getPattern(ds.orders.ord[i][j],true); for (int k=0; kdata[k][0]=reader.readS(); @@ -742,7 +742,7 @@ bool DivEngine::load(void* f, size_t slen) { pat->data[k][3]>>=1; } } - for (int l=0; leffectRows; l++) { + for (int l=0; ldata[k][4+(l<<1)]=reader.readS(); pat->data[k][5+(l<<1)]=reader.readS(); @@ -751,7 +751,6 @@ bool DivEngine::load(void* f, size_t slen) { pat->data[k][2]=reader.readS(); } } - ds.pat.push_back(chan); } ds.sampleLen=reader.readC(); @@ -947,16 +946,16 @@ bool DivEngine::save(FILE* f) { ERR_CHECK(fwrite(&i->data,4,i->len,f)); } - for (int i=0; ieffectRows,f)); + for (int i=0; igetPattern(song.orders.ord[i][j],false); + DivPattern* pat=song.pat[i].getPattern(song.orders.ord[i][j],false); for (int k=0; kdata[k][0],2,1,f)); // note ERR_CHECK(fwrite(&pat->data[k][1],2,1,f)); // octave ERR_CHECK(fwrite(&pat->data[k][3],2,1,f)); // volume - ERR_CHECK(fwrite(&pat->data[k][4],2,song.pat[i]->effectRows*2,f)); // volume + ERR_CHECK(fwrite(&pat->data[k][4],2,song.pat[i].effectRows*2,f)); // volume ERR_CHECK(fwrite(&pat->data[k][2],2,1,f)); // instrument } } @@ -1192,6 +1191,58 @@ void DivEngine::setView(DivStatusView which) { view=which; } +void DivEngine::initDispatch() { + if (dispatch!=NULL) return; + isBusy.lock(); + switch (song.system) { + case DIV_SYSTEM_GENESIS: + dispatch=new DivPlatformGenesis; + break; + case DIV_SYSTEM_GENESIS_EXT: + dispatch=new DivPlatformGenesisExt; + break; + case DIV_SYSTEM_SMS: + dispatch=new DivPlatformSMS; + break; + case DIV_SYSTEM_GB: + dispatch=new DivPlatformGB; + break; + case DIV_SYSTEM_PCE: + dispatch=new DivPlatformPCE; + break; + case DIV_SYSTEM_NES: + dispatch=new DivPlatformNES; + break; + case DIV_SYSTEM_C64_6581: + dispatch=new DivPlatformC64; + ((DivPlatformC64*)dispatch)->setChipModel(true); + break; + case DIV_SYSTEM_C64_8580: + dispatch=new DivPlatformC64; + ((DivPlatformC64*)dispatch)->setChipModel(false); + break; + case DIV_SYSTEM_ARCADE: + dispatch=new DivPlatformArcade; + break; + case DIV_SYSTEM_YM2610: + dispatch=new DivPlatformYM2610; + break; + default: + logW("this system is not supported yet! using dummy platform.\n"); + dispatch=new DivPlatformDummy; + break; + } + dispatch->init(this,getChannelCount(song.system),got.rate,(!song.pal) || (song.customTempo!=0 && song.hz<53)); + + blip_set_rates(bb[0],dispatch->rate,got.rate); + blip_set_rates(bb[1],dispatch->rate,got.rate); + isBusy.unlock(); +} + +void DivEngine::quitDispatch() { + if (dispatch==NULL) return; +} + bool DivEngine::init(String outName) { SNDFILE* outFile; SF_INFO outInfo; @@ -1266,49 +1317,7 @@ bool DivEngine::init(String outName) { vibTable[i]=127*sin(((double)i/64.0)*(2*M_PI)); } - switch (song.system) { - case DIV_SYSTEM_GENESIS: - dispatch=new DivPlatformGenesis; - break; - case DIV_SYSTEM_GENESIS_EXT: - dispatch=new DivPlatformGenesisExt; - break; - case DIV_SYSTEM_SMS: - dispatch=new DivPlatformSMS; - break; - case DIV_SYSTEM_GB: - dispatch=new DivPlatformGB; - break; - case DIV_SYSTEM_PCE: - dispatch=new DivPlatformPCE; - break; - case DIV_SYSTEM_NES: - dispatch=new DivPlatformNES; - break; - case DIV_SYSTEM_C64_6581: - dispatch=new DivPlatformC64; - ((DivPlatformC64*)dispatch)->setChipModel(true); - break; - case DIV_SYSTEM_C64_8580: - dispatch=new DivPlatformC64; - ((DivPlatformC64*)dispatch)->setChipModel(false); - break; - case DIV_SYSTEM_ARCADE: - dispatch=new DivPlatformArcade; - break; - case DIV_SYSTEM_YM2610: - dispatch=new DivPlatformYM2610; - break; - default: - logW("this system is not supported yet! using dummy platform.\n"); - dispatch=new DivPlatformDummy; - break; - } - dispatch->init(this,getChannelCount(song.system),got.rate,(!song.pal) || (song.customTempo!=0 && song.hz<53)); - - blip_set_rates(bb[0],dispatch->rate,got.rate); - blip_set_rates(bb[1],dispatch->rate,got.rate); - + initDispatch(); reset(); if (outName!="") { diff --git a/src/engine/pattern.cpp b/src/engine/pattern.cpp index 61961e503..5fe751f77 100644 --- a/src/engine/pattern.cpp +++ b/src/engine/pattern.cpp @@ -3,7 +3,7 @@ static DivPattern emptyPat; DivPattern::DivPattern() { - memset(data,0,256*16); + memset(data,-1,256*16); } DivPattern* DivChannelData::getPattern(int index, bool create) { diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 3e3791eee..51bd70d7c 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -307,9 +307,9 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char void DivEngine::processRow(int i, bool afterDelay) { int whatOrder=afterDelay?chan[i].delayOrder:curOrder; int whatRow=afterDelay?chan[i].delayRow:curRow; - DivPattern* pat=song.pat[i]->getPattern(song.orders.ord[i][whatOrder],false); + DivPattern* pat=song.pat[i].getPattern(song.orders.ord[i][whatOrder],false); // pre effects - if (!afterDelay) for (int j=0; jeffectRows; j++) { + if (!afterDelay) for (int j=0; jdata[whatRow][4+(j<<1)]; short effectVal=pat->data[whatRow][5+(j<<1)]; @@ -369,7 +369,7 @@ void DivEngine::processRow(int i, bool afterDelay) { } // effects - for (int j=0; jeffectRows; j++) { + for (int j=0; jdata[whatRow][4+(j<<1)]; short effectVal=pat->data[whatRow][5+(j<<1)]; @@ -526,7 +526,7 @@ void DivEngine::processRow(int i, bool afterDelay) { chan[i].nowYouCanStop=true; // post effects - for (int j=0; jeffectRows; j++) { + for (int j=0; jdata[whatRow][4+(j<<1)]; short effectVal=pat->data[whatRow][5+(j<<1)]; @@ -547,7 +547,7 @@ void DivEngine::nextRow() { snprintf(pb,4095," %.2x",song.orders.ord[i][curOrder]); strcat(pb1,pb); - DivPattern* pat=song.pat[i]->getPattern(song.orders.ord[i][curOrder],false); + DivPattern* pat=song.pat[i].getPattern(song.orders.ord[i][curOrder],false); snprintf(pb2,4095,"\x1b[37m %s", formatNote(pat->data[curRow][0],pat->data[curRow][1])); strcat(pb3,pb2); @@ -563,7 +563,7 @@ void DivEngine::nextRow() { snprintf(pb2,4095,"\x1b[0;36m%.2x",pat->data[curRow][2]); strcat(pb3,pb2); } - for (int j=0; jeffectRows; j++) { + for (int j=0; jdata[curRow][4+(j<<1)]==-1) { strcat(pb3,"\x1b[m--"); } else { @@ -621,7 +621,7 @@ void DivEngine::nextRow() { // post row details for (int i=0; igetPattern(song.orders.ord[i][curOrder],false); + DivPattern* pat=song.pat[i].getPattern(song.orders.ord[i][curOrder],false); if (!(pat->data[curRow][0]==0 && pat->data[curRow][1]==0)) { if (pat->data[curRow][0]!=100) { dispatchCmd(DivCommand(DIV_CMD_PRE_NOTE,i,ticks)); diff --git a/src/engine/song.h b/src/engine/song.h index 707e993f5..4739cda2b 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -91,7 +91,7 @@ struct DivSong { DivOrders orders; std::vector ins; - std::vector pat; + DivChannelData pat[17]; std::vector wave; std::vector sample; @@ -99,8 +99,8 @@ struct DivSong { DivWavetable nullWave; DivSong(): - version(0), - system(DIV_SYSTEM_NULL), + version(24), + system(DIV_SYSTEM_GENESIS), name(""), author(""), carrier(""), @@ -123,8 +123,8 @@ struct DivSong { pal(false), customTempo(false), hz(60), - patLen(0), - ordersLen(0), + patLen(64), + ordersLen(1), insLen(0), waveLen(0), sampleLen(0) { diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 3f457adc7..c4cff671a 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -492,7 +492,7 @@ bool FurnaceGUI::loop() { ImGui::TableNextColumn(); ImGui::Text("%3d ",i); for (int j=0; jsong.pat[j]->getPattern(e->song.orders.ord[j][ord],true); + DivPattern* pat=e->song.pat[j].getPattern(e->song.orders.ord[j][ord],true); ImGui::TableNextColumn(); sprintf(id,"%s##PN_%d_%d",noteName(pat->data[i][0],pat->data[i][1]),i,j); @@ -514,7 +514,7 @@ bool FurnaceGUI::loop() { ImGui::SameLine(0.0f,0.0f); ImGui::Selectable(id,false,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars); - for (int k=0; ksong.pat[j]->effectRows; k++) { + for (int k=0; ksong.pat[j].effectRows; k++) { int index=4+(k<<1); if (pat->data[i][index]==-1) { sprintf(id,"..##PE%d_%d_%d",k,i,j); diff --git a/src/main.cpp b/src/main.cpp index b55880c55..ec14cdc4e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -235,52 +235,54 @@ int main(int argc, char** argv) { } } - if (fileName.empty()) { + if (fileName.empty() && consoleMode) { logI("usage: %s file\n",argv[0]); return 1; } logI("Furnace version " DIV_VERSION ".\n"); - logI("loading module...\n"); - FILE* f=fopen(fileName.c_str(),"rb"); - if (f==NULL) { - perror("error"); - return 1; - } - if (fseek(f,0,SEEK_END)<0) { - perror("size error"); - fclose(f); - return 1; - } - ssize_t len=ftell(f); - if (len==0x7fffffffffffffff) { - perror("could not get file length"); - fclose(f); - return 1; - } - if (len<1) { - if (len==0) { - printf("that file is empty!\n"); - } else { - perror("tell error"); + if (!fileName.empty()) { + logI("loading module...\n"); + FILE* f=fopen(fileName.c_str(),"rb"); + if (f==NULL) { + perror("error"); + return 1; + } + if (fseek(f,0,SEEK_END)<0) { + perror("size error"); + fclose(f); + return 1; + } + ssize_t len=ftell(f); + if (len==0x7fffffffffffffff) { + perror("could not get file length"); + fclose(f); + return 1; + } + if (len<1) { + if (len==0) { + printf("that file is empty!\n"); + } else { + perror("tell error"); + } + fclose(f); + return 1; + } + unsigned char* file=new unsigned char[len]; + if (fseek(f,0,SEEK_SET)<0) { + perror("size error"); + fclose(f); + return 1; + } + if (fread(file,1,(size_t)len,f)!=(size_t)len) { + perror("read error"); + fclose(f); + return 1; } fclose(f); - return 1; - } - unsigned char* file=new unsigned char[len]; - if (fseek(f,0,SEEK_SET)<0) { - perror("size error"); - fclose(f); - return 1; - } - if (fread(file,1,(size_t)len,f)!=(size_t)len) { - perror("read error"); - fclose(f); - return 1; - } - fclose(f); - if (!e.load((void*)file,(size_t)len)) { - logE("could not open file!\n"); - return 1; + if (!e.load((void*)file,(size_t)len)) { + logE("could not open file!\n"); + return 1; + } } /*FILE* outFile=fopen("testout.dmf","wb"); if (outFile!=NULL) {