diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 1a9cc810..05936833 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -515,6 +515,13 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { if (ds.system[0]==DIV_SYSTEM_C64_8580 || ds.system[0]==DIV_SYSTEM_C64_6581) { ins->type=DIV_INS_C64; } + if (ds.system[0]==DIV_SYSTEM_YM2610 || ds.system[0]==DIV_SYSTEM_YM2610_EXT) { + ins->std.dutyMacroHeight=31; + ins->std.waveMacroHeight=7; + } + if (ds.system[0]==DIV_SYSTEM_PCE) { + ins->std.volMacroHeight=31; + } if (ins->mode) { // FM ins->fm.alg=reader.readC(); @@ -712,6 +719,9 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { for (int i=0; ilen=(unsigned char)reader.readI(); + if (ds.system[0]==DIV_SYSTEM_GB) { + wave->max=15; + } if (wave->len>32) { logE("invalid wave length %d. are we doing something wrong?\n",wave->len); lastError="file is corrupt or unreadable at wavetables"; diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index 01506de5..0a8c4fa8 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -19,8 +19,13 @@ void DivPlatformGB::updateWave() { DivWavetable* wt=parent->getWave(chan[2].wave); rWrite(0x1a,0); for (int i=0; i<16; i++) { - unsigned char next=((wt->data[i*2]&15)<<4)|(wt->data[1+i*2]&15); - rWrite(0x30+i,next); + if (wt->max<1 || wt->len<1) { + rWrite(0x30+i,0); + } else { + unsigned char nibble1=(wt->data[(i*2)*wt->len/32]*15)/wt->max; + unsigned char nibble2=(wt->data[(1+i*2)*wt->len/32]*15)/wt->max; + rWrite(0x30+i,(nibble1<<4)|nibble2); + } } } diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index 9ab2c10a..0afb1958 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -64,7 +64,11 @@ void DivPlatformPCE::updateWave(int ch) { chWrite(ch,0x04,0x5f); chWrite(ch,0x04,0x1f); for (int i=0; i<32; i++) { - chWrite(ch,0x06,wt->data[i]&31); + if (wt->max<1 || wt->len<1) { + chWrite(ch,0x06,0); + } else { + chWrite(ch,0x06,wt->data[i*wt->len/32]*31/wt->max); + } } if (chan[ch].active) { chWrite(ch,0x04,0x80|chan[ch].outVol); diff --git a/src/engine/wavetable.h b/src/engine/wavetable.h index bd115aa7..7764968d 100644 --- a/src/engine/wavetable.h +++ b/src/engine/wavetable.h @@ -1,12 +1,12 @@ struct DivWavetable { int len, min, max; - int data[32]; + int data[256]; DivWavetable(): len(32), min(0), max(31) { - for (int i=0; i<32; i++) { + for (int i=0; i<256; i++) { data[i]=i; } } diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 249d1c80..afea97ab 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -1046,11 +1046,32 @@ void FurnaceGUI::drawWaveList() { void FurnaceGUI::drawWaveEdit() { if (!waveEditOpen) return; float wavePreview[256]; - if (ImGui::Begin("Wavetable Editor",&waveEditOpen)) { + if (ImGui::Begin("Wavetable Editor",&waveEditOpen,ImGuiWindowFlags_NoDocking)) { if (curWave<0 || curWave>=(int)e->song.wave.size()) { ImGui::Text("no wavetable selected"); } else { DivWavetable* wave=e->song.wave[curWave]; + ImGui::Text("Width"); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("use a width of 32 on Game Boy and PC Engine.\nany other widths will be scaled during playback."); + } + ImGui::SameLine(); + ImGui::SetNextItemWidth(128.0f*dpiScale); + if (ImGui::InputInt("##_WTW",&wave->len,1,2)) { + if (wave->len>256) wave->len=256; + if (wave->len<1) wave->len=1; + } + ImGui::SameLine(); + ImGui::Text("Height"); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("use a height of:\n- 15 for Game Boy\n- 31 for PC Engine\nany other heights will be scaled during playback."); + } + ImGui::SameLine(); + ImGui::SetNextItemWidth(128.0f*dpiScale); + if (ImGui::InputInt("##_WTH",&wave->max,1,2)) { + if (wave->max>255) wave->max=255; + if (wave->max<1) wave->max=1; + } for (int i=0; ilen; i++) { wavePreview[i]=wave->data[i]; } @@ -1139,7 +1160,7 @@ void FurnaceGUI::drawSampleList() { void FurnaceGUI::drawSampleEdit() { if (!sampleEditOpen) return; - if (ImGui::Begin("Sample Editor",&sampleEditOpen)) { + if (ImGui::Begin("Sample Editor",&sampleEditOpen,ImGuiWindowFlags_NoDocking)) { if (curSample<0 || curSample>=(int)e->song.sample.size()) { ImGui::Text("no sample selected"); } else {