diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 708dc742..5f49e5d6 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -318,11 +318,12 @@ int DivEngine::getMaxWave() { return 0; } -bool DivEngine::load(void* f, size_t slen) { +bool DivEngine::load(unsigned char* f, size_t slen) { unsigned char* file; size_t len; if (slen<16) { logE("too small!"); + delete[] f; return false; } if (memcmp(f,DIV_DMF_MAGIC,16)!=0) { @@ -345,6 +346,8 @@ bool DivEngine::load(void* f, size_t slen) { } else { logE("zlib error: %s\n",zl.msg); } + inflateEnd(&zl); + delete[] f; return false; } @@ -364,6 +367,8 @@ bool DivEngine::load(void* f, size_t slen) { for (InflateBlock* i: blocks) delete i; blocks.clear(); delete ib; + inflateEnd(&zl); + delete[] f; return false; } ib->blockSize=ib->len-zl.avail_out; @@ -381,6 +386,7 @@ bool DivEngine::load(void* f, size_t slen) { } for (InflateBlock* i: blocks) delete i; blocks.clear(); + delete[] f; return false; } @@ -393,6 +399,7 @@ bool DivEngine::load(void* f, size_t slen) { logE("compressed too small!\n"); for (InflateBlock* i: blocks) delete i; blocks.clear(); + delete[] f; return false; } file=new unsigned char[finalSize]; @@ -403,6 +410,7 @@ bool DivEngine::load(void* f, size_t slen) { } blocks.clear(); len=finalSize; + delete[] f; } else { logD("loading as uncompressed\n"); file=(unsigned char*)f; @@ -410,6 +418,7 @@ bool DivEngine::load(void* f, size_t slen) { } if (memcmp(file,DIV_DMF_MAGIC,16)!=0) { logE("not a valid module!\n"); + delete[] file; return false; } SafeReader reader=SafeReader(file,len); @@ -423,6 +432,7 @@ bool DivEngine::load(void* f, size_t slen) { if (!reader.seek(16,SEEK_SET)) { logE("premature end of file!"); + delete[] file; return false; } ds.version=reader.readC(); @@ -438,6 +448,7 @@ bool DivEngine::load(void* f, size_t slen) { } if (ds.system==DIV_SYSTEM_NULL) { logE("invalid system 0x%.2x!",sys); + delete[] file; return false; } @@ -539,6 +550,7 @@ bool DivEngine::load(void* f, size_t slen) { if (ins->mode) { // FM if (!isFMSystem(ds.system)) { logE("FM instrument in non-FM system. oopsie?\n"); + delete[] file; return false; } ins->fm.alg=reader.readC(); @@ -559,6 +571,7 @@ bool DivEngine::load(void* f, size_t slen) { } if (ins->fm.ops!=2 && ins->fm.ops!=4) { logE("invalid op count %d. did we read it wrong?\n",ins->fm.ops); + delete[] file; return false; } ins->fm.ams=reader.readC(); @@ -725,6 +738,7 @@ bool DivEngine::load(void* f, size_t slen) { wave->len=(unsigned char)reader.readI(); if (wave->len>32) { logE("invalid wave length %d. are we doing something wrong?\n",wave->len); + delete[] file; return false; } logD("%d length %d\n",i,wave->len); @@ -750,6 +764,7 @@ bool DivEngine::load(void* f, size_t slen) { 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); + delete[] file; return false; } for (int j=0; jlength=reader.readI(); if (sample->length<0) { logE("invalid sample length %d. are we doing something wrong?\n",sample->length); + delete[] file; return false; } if (ds.version>0x16) { @@ -844,8 +860,10 @@ bool DivEngine::load(void* f, size_t slen) { renderSamples(); } catch (EndOfFileException e) { logE("premature end of file!\n"); + delete[] file; return false; } + delete[] file; return true; } diff --git a/src/engine/engine.h b/src/engine/engine.h index 72c44da7..73d483b4 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -7,6 +7,9 @@ #include "blip_buf.h" #include +#define DIV_VERSION "0.1" +#define DIV_ENGINE_VERSION 11 + enum DivStatusView { DIV_STATUS_NOTHING=0, DIV_STATUS_PATTERN, @@ -103,7 +106,7 @@ class DivEngine { DivInstrument* getIns(int index); DivWavetable* getWave(int index); // load a .dmf. - bool load(void* f, size_t length); + bool load(unsigned char* f, size_t length); // save as .dmf. SafeWriter* save(); diff --git a/src/engine/sample.cpp b/src/engine/sample.cpp index a07068ee..0dd2c851 100644 --- a/src/engine/sample.cpp +++ b/src/engine/sample.cpp @@ -1,7 +1,7 @@ #include "sample.h" DivSample::~DivSample() { - if (data) delete data; - if (rendData) delete rendData; - if (adpcmRendData) delete adpcmRendData; + if (data) delete[] data; + if (rendData) delete[] rendData; + if (adpcmRendData) delete[] adpcmRendData; } diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 5d6abe1f..b11b1e2f 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -122,6 +122,13 @@ void FurnaceGUI::drawEditControls() { if (curOctave<0) curOctave=0; } + ImGui::Text("Edit Step"); + ImGui::SameLine(); + if (ImGui::InputInt("##EditStep",&editStep,1,1)) { + if (editStep>=e->song.patLen) editStep=e->song.patLen-1; + if (editStep<0) editStep=0; + } + if (ImGui::Button("Play")) { e->play(); } @@ -170,6 +177,16 @@ void FurnaceGUI::drawSongInfo() { ImGui::SetNextItemWidth(120.0f*dpiScale); ImGui::InputScalar("##Highlight2",ImGuiDataType_U8,&e->song.hilightB,&_ONE,&_THREE); + ImGui::Text("Pattern Length"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(120.0f*dpiScale); + int patLen=e->song.patLen; + if (ImGui::InputInt("##PatLength",&patLen,1,3)) { + if (patLen<1) patLen=1; + if (patLen>256) patLen=256; + e->song.patLen=patLen; + } + ImGui::Text("Rate"); ImGui::SameLine(); ImGui::SetNextItemWidth(120.0f*dpiScale); @@ -200,26 +217,38 @@ void FurnaceGUI::drawOrders() { ImGui::TableSetupScrollFreeze(0,1); ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_ROW_INDEX]); for (int i=0; igetChannelCount(e->song.system); i++) { ImGui::TableNextColumn(); ImGui::Text("%s",e->getChannelShortName(i)); } + ImGui::PopStyleColor(); for (int i=0; isong.ordersLen; i++) { ImGui::TableNextRow(); if (e->getOrder()==i) ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0,0x40ffffff); ImGui::TableNextColumn(); + ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_ROW_INDEX]); snprintf(selID,16,"%.2x##O_S%.2x",i,i); if (ImGui::Selectable(selID)) { e->setOrder(i); } + ImGui::PopStyleColor(); for (int j=0; jgetChannelCount(e->song.system); j++) { ImGui::TableNextColumn(); snprintf(selID,16,"%.2x##O_%.2x_%.2x",e->song.orders.ord[j][i],j,i); if (ImGui::Selectable(selID)) { - if (e->song.orders.ord[j][i]<0x7f) e->song.orders.ord[j][i]++; + if (e->getOrder()==i) { + if (e->song.orders.ord[j][i]<0x7f) e->song.orders.ord[j][i]++; + } else { + e->setOrder(i); + } } if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) { - if (e->song.orders.ord[j][i]>0) e->song.orders.ord[j][i]--; + if (e->getOrder()==i) { + if (e->song.orders.ord[j][i]>0) e->song.orders.ord[j][i]--; + } else { + e->setOrder(i); + } } } } @@ -239,6 +268,11 @@ void FurnaceGUI::drawInsList() { if (ImGui::Selectable(fmt::sprintf("%d: %s##_INS%d\n",i,ins->name,i).c_str(),curIns==i)) { curIns=i; } + if (ImGui::IsItemHovered()) { + if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) { + insEditOpen=true; + } + } } } if (ImGui::IsWindowFocused()) curWindow=GUI_WINDOW_INS_LIST; @@ -1048,16 +1082,18 @@ int FurnaceGUI::load(String path) { if (fseek(f,0,SEEK_SET)<0) { perror("size error"); fclose(f); + delete[] file; return 1; } if (fread(file,1,(size_t)len,f)!=(size_t)len) { perror("read error"); fclose(f); + delete[] file; return 1; } fclose(f); e->quitDispatch(); - if (!e->load((void*)file,(size_t)len)) { + if (!e->load(file,(size_t)len)) { logE("could not open file!\n"); return 1; } @@ -1145,11 +1181,31 @@ bool FurnaceGUI::loop() { isSaving=true; } ImGui::Separator(); + ImGui::MenuItem("change platform..."); + ImGui::Separator(); if (ImGui::MenuItem("exit")) { quit=true; } ImGui::EndMenu(); } + if (ImGui::BeginMenu("edit")) { + ImGui::MenuItem("undo"); + ImGui::MenuItem("redo"); + ImGui::Separator(); + ImGui::MenuItem("cut"); + ImGui::MenuItem("copy"); + ImGui::MenuItem("paste"); + ImGui::MenuItem("delete"); + ImGui::MenuItem("select all"); + ImGui::Separator(); + ImGui::MenuItem("note up"); + ImGui::MenuItem("note down"); + ImGui::MenuItem("octave up"); + ImGui::MenuItem("octave down"); + ImGui::Separator(); + ImGui::MenuItem("clear..."); + ImGui::EndMenu(); + } if (ImGui::BeginMenu("window")) { if (ImGui::MenuItem("play/edit controls")) editControlsOpen=!editControlsOpen; if (ImGui::MenuItem("song information")) songInfoOpen=!songInfoOpen; @@ -1159,6 +1215,10 @@ bool FurnaceGUI::loop() { if (ImGui::MenuItem("pattern")) patternOpen=!patternOpen; ImGui::EndMenu(); } + if (ImGui::BeginMenu("help")) { + ImGui::MenuItem("about..."); + ImGui::EndMenu(); + } ImGui::EndMainMenuBar(); ImGui::DockSpaceOverViewport(); diff --git a/src/main.cpp b/src/main.cpp index b0cb5a7d..39124022 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,8 +15,6 @@ #include "gui/gui.h" #endif -#define DIV_VERSION "dev10" - DivEngine e; #ifdef HAVE_GUI @@ -270,15 +268,17 @@ int main(int argc, char** argv) { if (fseek(f,0,SEEK_SET)<0) { perror("size error"); fclose(f); + delete[] file; return 1; } if (fread(file,1,(size_t)len,f)!=(size_t)len) { perror("read error"); fclose(f); + delete[] file; return 1; } fclose(f); - if (!e.load((void*)file,(size_t)len)) { + if (!e.load(file,(size_t)len)) { logE("could not open file!\n"); return 1; }