mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-16 01:35:07 +00:00
waveform width/height controls
This commit is contained in:
parent
02b5b05e04
commit
5637639950
5 changed files with 47 additions and 7 deletions
|
@ -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) {
|
if (ds.system[0]==DIV_SYSTEM_C64_8580 || ds.system[0]==DIV_SYSTEM_C64_6581) {
|
||||||
ins->type=DIV_INS_C64;
|
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
|
if (ins->mode) { // FM
|
||||||
ins->fm.alg=reader.readC();
|
ins->fm.alg=reader.readC();
|
||||||
|
@ -712,6 +719,9 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
for (int i=0; i<ds.waveLen; i++) {
|
for (int i=0; i<ds.waveLen; i++) {
|
||||||
DivWavetable* wave=new DivWavetable;
|
DivWavetable* wave=new DivWavetable;
|
||||||
wave->len=(unsigned char)reader.readI();
|
wave->len=(unsigned char)reader.readI();
|
||||||
|
if (ds.system[0]==DIV_SYSTEM_GB) {
|
||||||
|
wave->max=15;
|
||||||
|
}
|
||||||
if (wave->len>32) {
|
if (wave->len>32) {
|
||||||
logE("invalid wave length %d. are we doing something wrong?\n",wave->len);
|
logE("invalid wave length %d. are we doing something wrong?\n",wave->len);
|
||||||
lastError="file is corrupt or unreadable at wavetables";
|
lastError="file is corrupt or unreadable at wavetables";
|
||||||
|
|
|
@ -19,8 +19,13 @@ void DivPlatformGB::updateWave() {
|
||||||
DivWavetable* wt=parent->getWave(chan[2].wave);
|
DivWavetable* wt=parent->getWave(chan[2].wave);
|
||||||
rWrite(0x1a,0);
|
rWrite(0x1a,0);
|
||||||
for (int i=0; i<16; i++) {
|
for (int i=0; i<16; i++) {
|
||||||
unsigned char next=((wt->data[i*2]&15)<<4)|(wt->data[1+i*2]&15);
|
if (wt->max<1 || wt->len<1) {
|
||||||
rWrite(0x30+i,next);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,11 @@ void DivPlatformPCE::updateWave(int ch) {
|
||||||
chWrite(ch,0x04,0x5f);
|
chWrite(ch,0x04,0x5f);
|
||||||
chWrite(ch,0x04,0x1f);
|
chWrite(ch,0x04,0x1f);
|
||||||
for (int i=0; i<32; i++) {
|
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) {
|
if (chan[ch].active) {
|
||||||
chWrite(ch,0x04,0x80|chan[ch].outVol);
|
chWrite(ch,0x04,0x80|chan[ch].outVol);
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
struct DivWavetable {
|
struct DivWavetable {
|
||||||
int len, min, max;
|
int len, min, max;
|
||||||
int data[32];
|
int data[256];
|
||||||
|
|
||||||
DivWavetable():
|
DivWavetable():
|
||||||
len(32),
|
len(32),
|
||||||
min(0),
|
min(0),
|
||||||
max(31) {
|
max(31) {
|
||||||
for (int i=0; i<32; i++) {
|
for (int i=0; i<256; i++) {
|
||||||
data[i]=i;
|
data[i]=i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1046,11 +1046,32 @@ void FurnaceGUI::drawWaveList() {
|
||||||
void FurnaceGUI::drawWaveEdit() {
|
void FurnaceGUI::drawWaveEdit() {
|
||||||
if (!waveEditOpen) return;
|
if (!waveEditOpen) return;
|
||||||
float wavePreview[256];
|
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()) {
|
if (curWave<0 || curWave>=(int)e->song.wave.size()) {
|
||||||
ImGui::Text("no wavetable selected");
|
ImGui::Text("no wavetable selected");
|
||||||
} else {
|
} else {
|
||||||
DivWavetable* wave=e->song.wave[curWave];
|
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; i<wave->len; i++) {
|
for (int i=0; i<wave->len; i++) {
|
||||||
wavePreview[i]=wave->data[i];
|
wavePreview[i]=wave->data[i];
|
||||||
}
|
}
|
||||||
|
@ -1139,7 +1160,7 @@ void FurnaceGUI::drawSampleList() {
|
||||||
|
|
||||||
void FurnaceGUI::drawSampleEdit() {
|
void FurnaceGUI::drawSampleEdit() {
|
||||||
if (!sampleEditOpen) return;
|
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()) {
|
if (curSample<0 || curSample>=(int)e->song.sample.size()) {
|
||||||
ImGui::Text("no sample selected");
|
ImGui::Text("no sample selected");
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue