allow running GUI without loaded module
This commit is contained in:
parent
6b499fbc79
commit
285cc9b766
|
@ -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; i<getChannelCount(ds.system); i++) {
|
||||
DivChannelData* chan=new DivChannelData;
|
||||
DivChannelData& chan=ds.pat[i];
|
||||
if (ds.version<0x0a) {
|
||||
chan->effectRows=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; j<ds.ordersLen; j++) {
|
||||
DivPattern* pat=chan->getPattern(ds.orders.ord[i][j],true);
|
||||
DivPattern* pat=chan.getPattern(ds.orders.ord[i][j],true);
|
||||
for (int k=0; k<ds.patLen; k++) {
|
||||
// note
|
||||
pat->data[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; l<chan->effectRows; l++) {
|
||||
for (int l=0; l<chan.effectRows; l++) {
|
||||
// effect
|
||||
pat->data[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; i<song.pat.size(); i++) {
|
||||
ERR_CHECK(fputc(song.pat[i]->effectRows,f));
|
||||
for (int i=0; i<getChannelCount(song.system); i++) {
|
||||
ERR_CHECK(fputc(song.pat[i].effectRows,f));
|
||||
|
||||
for (int j=0; j<song.ordersLen; j++) {
|
||||
DivPattern* pat=song.pat[i]->getPattern(song.orders.ord[i][j],false);
|
||||
DivPattern* pat=song.pat[i].getPattern(song.orders.ord[i][j],false);
|
||||
for (int k=0; k<song.patLen; k++) {
|
||||
ERR_CHECK(fwrite(&pat->data[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!="") {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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; j<song.pat[i]->effectRows; j++) {
|
||||
if (!afterDelay) for (int j=0; j<song.pat[i].effectRows; j++) {
|
||||
short effect=pat->data[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; j<song.pat[i]->effectRows; j++) {
|
||||
for (int j=0; j<song.pat[i].effectRows; j++) {
|
||||
short effect=pat->data[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; j<song.pat[i]->effectRows; j++) {
|
||||
for (int j=0; j<song.pat[i].effectRows; j++) {
|
||||
short effect=pat->data[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; j<song.pat[i]->effectRows; j++) {
|
||||
for (int j=0; j<song.pat[i].effectRows; j++) {
|
||||
if (pat->data[curRow][4+(j<<1)]==-1) {
|
||||
strcat(pb3,"\x1b[m--");
|
||||
} else {
|
||||
|
@ -621,7 +621,7 @@ void DivEngine::nextRow() {
|
|||
|
||||
// post row details
|
||||
for (int i=0; i<chans; i++) {
|
||||
DivPattern* pat=song.pat[i]->getPattern(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));
|
||||
|
|
|
@ -91,7 +91,7 @@ struct DivSong {
|
|||
|
||||
DivOrders orders;
|
||||
std::vector<DivInstrument*> ins;
|
||||
std::vector<DivChannelData*> pat;
|
||||
DivChannelData pat[17];
|
||||
std::vector<DivWavetable*> wave;
|
||||
std::vector<DivSample*> 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) {
|
||||
|
|
|
@ -492,7 +492,7 @@ bool FurnaceGUI::loop() {
|
|||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%3d ",i);
|
||||
for (int j=0; j<chans; j++) {
|
||||
DivPattern* pat=e->song.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; k<e->song.pat[j]->effectRows; k++) {
|
||||
for (int k=0; k<e->song.pat[j].effectRows; k++) {
|
||||
int index=4+(k<<1);
|
||||
if (pat->data[i][index]==-1) {
|
||||
sprintf(id,"..##PE%d_%d_%d",k,i,j);
|
||||
|
|
82
src/main.cpp
82
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) {
|
||||
|
|
Loading…
Reference in New Issue