mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-13 00:05:06 +00:00
Merge remote-tracking branch 'upstream/master' into es5506_alt
This commit is contained in:
commit
a3bca9efa7
20 changed files with 184 additions and 94 deletions
1
TODO.md
1
TODO.md
|
@ -17,7 +17,6 @@
|
|||
- volume commands should work on Game Boy
|
||||
- add another FM editor layout
|
||||
- if macros have release, note off should release them
|
||||
- add ability to select a column by double clicking
|
||||
- add ability to move selection by dragging
|
||||
- Apply button in settings
|
||||
- find and replace
|
||||
|
|
27
extern/imgui_patched/imgui_internal.h
vendored
27
extern/imgui_patched/imgui_internal.h
vendored
|
@ -566,9 +566,8 @@ struct ImBitArray
|
|||
void SetBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArraySetBit(Storage, n); }
|
||||
void ClearBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArrayClearBit(Storage, n); }
|
||||
void SetBitRange(int n, int n2) { n += OFFSET; n2 += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT && n2 > n && n2 <= BITCOUNT); ImBitArraySetBitRange(Storage, n, n2); } // Works on range [n..n2)
|
||||
bool operator[](int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return ImBitArrayTestBit(Storage, n); }
|
||||
ImBitArray& operator|=(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArraySetBit(Storage, n); return *this; }
|
||||
bool operator&(int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return ImBitArrayTestBit(Storage, n); }
|
||||
bool operator[](int n) const { return TestBit(n); }
|
||||
bool operator&(int n) const { return TestBit(n); }
|
||||
bool operator==(ImBitArray const &a) const
|
||||
{
|
||||
for (int i = 0; i < ((BITCOUNT + 31) >> 5); ++i)
|
||||
|
@ -614,23 +613,17 @@ struct IMGUI_API ImBitVector
|
|||
void SetBit(int n) { IM_ASSERT(n >= 0 && n < BitCount); ImBitArraySetBit(Storage.Data, n); }
|
||||
void SetBitRange(int n, int n2) { IM_ASSERT(n >= 0 && n < BitCount && n2 > n && n2 <= BitCount); ImBitArraySetBitRange(Storage.Data, n, n2); } // Works on range [n..n2)
|
||||
void ClearBit(int n) { IM_ASSERT(n >= 0 && n < BitCount); ImBitArrayClearBit(Storage.Data, n); }
|
||||
bool operator[](int n) const { IM_ASSERT(n >= 0 && n < BitCount); return ImBitArrayTestBit(Storage.Data, n); }
|
||||
ImBitVector& operator|=(int n) { IM_ASSERT(n >= 0 && n < BitCount); ImBitArraySetBit(Storage.Data, n); return *this; }
|
||||
bool operator&(int n) const { IM_ASSERT(n >= 0 && n < BitCount); return ImBitArrayTestBit(Storage.Data, n); }
|
||||
bool operator==(ImBitVector const &a) const
|
||||
bool CheckEqual(ImBitVector const &a) const
|
||||
{
|
||||
for (int i = 0; i < ImMin((a.BitCount + 31) >> 5, (BitCount + 31) >> 5); ++i)
|
||||
if (Storage[i] != a.Storage[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool operator!=(ImBitVector const &a) const
|
||||
{
|
||||
for (int i = 0; i < ImMin((a.BitCount + 31) >> 5, (BitCount + 31) >> 5); ++i)
|
||||
if (Storage[i] == a.Storage[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool operator[](int n) const { return TestBit(n); }
|
||||
bool operator&(int n) const { return TestBit(n); }
|
||||
bool operator==(ImBitVector const &a) const { return CheckEqual(a); }
|
||||
bool operator!=(ImBitVector const &a) const { return !CheckEqual(a); }
|
||||
};
|
||||
|
||||
// Helper: ImSpan<>
|
||||
|
@ -2503,8 +2496,8 @@ struct IMGUI_API ImGuiTabBar
|
|||
#define IMGUI_TABLE_DRAW_CHANNELS(c) (4 + (c) * 2) // See TableSetupDrawChannels()
|
||||
|
||||
// Our current column maximum is IMGUI_TABLE_MAX_COLUMNS but we may raise that in the future.
|
||||
typedef ImS32 ImGuiTableColumnIdx;
|
||||
typedef ImU32 ImGuiTableDrawChannelIdx;
|
||||
typedef ImS16 ImGuiTableColumnIdx;
|
||||
typedef ImU16 ImGuiTableDrawChannelIdx;
|
||||
|
||||
// [Internal] sizeof() ~ 104
|
||||
// We use the terminology "Enabled" to refer to a column that is not Hidden by user/api.
|
||||
|
@ -2563,7 +2556,7 @@ struct ImGuiTableColumn
|
|||
PrevEnabledColumn = NextEnabledColumn = -1;
|
||||
SortOrder = -1;
|
||||
SortDirection = ImGuiSortDirection_None;
|
||||
DrawChannelCurrent = DrawChannelFrozen = DrawChannelUnfrozen = (ImU32)-1;
|
||||
DrawChannelCurrent = DrawChannelFrozen = DrawChannelUnfrozen = (ImU16)-1;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
37
extern/imgui_patched/imgui_tables.cpp
vendored
37
extern/imgui_patched/imgui_tables.cpp
vendored
|
@ -797,8 +797,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||
else
|
||||
table->LeftMostEnabledColumn = (ImGuiTableColumnIdx)column_n;
|
||||
column->IndexWithinEnabledSet = table->ColumnsEnabledCount++;
|
||||
table->EnabledMaskByIndex |= column_n;
|
||||
table->EnabledMaskByDisplayOrder |= column->DisplayOrder;
|
||||
table->EnabledMaskByIndex.SetBit(column_n);
|
||||
table->EnabledMaskByDisplayOrder.SetBit(column->DisplayOrder);
|
||||
prev_visible_column_idx = column_n;
|
||||
IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder);
|
||||
|
||||
|
@ -846,7 +846,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||
table->LeftMostStretchedColumn = table->RightMostStretchedColumn = -1;
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
{
|
||||
if (!(table->EnabledMaskByIndex & column_n))
|
||||
if (!table->EnabledMaskByIndex.TestBit(column_n))
|
||||
continue;
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
|
||||
|
@ -862,7 +862,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||
// Latch initial size for fixed columns and update it constantly for auto-resizing column (unless clipped!)
|
||||
if (column->AutoFitQueue != 0x00)
|
||||
column->WidthRequest = width_auto;
|
||||
else if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !column_is_resizable && (table->RequestOutputMaskByIndex & column_n))
|
||||
else if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !column_is_resizable && (table->RequestOutputMaskByIndex.TestBit(column_n)))
|
||||
column->WidthRequest = width_auto;
|
||||
|
||||
// FIXME-TABLE: Increase minimum size during init frame to avoid biasing auto-fitting widgets
|
||||
|
@ -909,7 +909,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||
table->ColumnsGivenWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount;
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
{
|
||||
if (!(table->EnabledMaskByIndex & column_n))
|
||||
if (!table->EnabledMaskByIndex.TestBit(column_n))
|
||||
continue;
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
|
||||
|
@ -936,7 +936,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||
if (width_remaining_for_stretched_columns >= 1.0f && !(table->Flags & ImGuiTableFlags_PreciseWidths))
|
||||
for (int order_n = table->ColumnsCount - 1; stretch_sum_weights > 0.0f && width_remaining_for_stretched_columns >= 1.0f && order_n >= 0; order_n--)
|
||||
{
|
||||
if (!(table->EnabledMaskByDisplayOrder & order_n))
|
||||
if (!table->EnabledMaskByDisplayOrder.TestBit(order_n))
|
||||
continue;
|
||||
ImGuiTableColumn* column = &table->Columns[table->DisplayOrderToIndex[order_n]];
|
||||
if (!(column->Flags & ImGuiTableColumnFlags_WidthStretch))
|
||||
|
@ -977,7 +977,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||
// Clear status flags
|
||||
column->Flags &= ~ImGuiTableColumnFlags_StatusMask_;
|
||||
|
||||
if ((table->EnabledMaskByDisplayOrder & order_n) == 0)
|
||||
if (!table->EnabledMaskByDisplayOrder.TestBit(order_n))
|
||||
{
|
||||
// Hidden column: clear a few fields and we are done with it for the remainder of the function.
|
||||
// We set a zero-width clip rect but set Min.y/Max.y properly to not interfere with the clipper.
|
||||
|
@ -1030,12 +1030,12 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||
column->IsVisibleY = true; // (column->ClipRect.Max.y > column->ClipRect.Min.y);
|
||||
const bool is_visible = column->IsVisibleX; //&& column->IsVisibleY;
|
||||
if (is_visible)
|
||||
table->VisibleMaskByIndex |= column_n;
|
||||
table->VisibleMaskByIndex.SetBit(column_n);
|
||||
|
||||
// Mark column as requesting output from user. Note that fixed + non-resizable sets are auto-fitting at all times and therefore always request output.
|
||||
column->IsRequestOutput = is_visible || column->AutoFitQueue != 0 || column->CannotSkipItemsQueue != 0;
|
||||
if (column->IsRequestOutput)
|
||||
table->RequestOutputMaskByIndex |= column_n;
|
||||
table->RequestOutputMaskByIndex.SetBit(column_n);
|
||||
|
||||
// Mark column as SkipItems (ignoring all items/layout)
|
||||
column->IsSkipItems = !column->IsEnabled || table->HostSkipItems;
|
||||
|
@ -1163,7 +1163,7 @@ void ImGui::TableUpdateBorders(ImGuiTable* table)
|
|||
|
||||
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
|
||||
{
|
||||
if (!(table->EnabledMaskByDisplayOrder & order_n))
|
||||
if (!table->EnabledMaskByDisplayOrder.TestBit(order_n))
|
||||
continue;
|
||||
|
||||
const int column_n = table->DisplayOrderToIndex[order_n];
|
||||
|
@ -1299,7 +1299,7 @@ void ImGui::EndTable()
|
|||
float auto_fit_width_for_stretched = 0.0f;
|
||||
float auto_fit_width_for_stretched_min = 0.0f;
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
if (table->EnabledMaskByIndex & column_n)
|
||||
if (table->EnabledMaskByIndex.TestBit(column_n))
|
||||
{
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
float column_width_request = ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !(column->Flags & ImGuiTableColumnFlags_NoResize)) ? column->WidthRequest : TableGetColumnWidthAuto(table, column);
|
||||
|
@ -1645,7 +1645,7 @@ void ImGui::TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n
|
|||
return;
|
||||
if (column_n == -1)
|
||||
column_n = table->CurrentColumn;
|
||||
if ((table->VisibleMaskByIndex & column_n) == 0)
|
||||
if (!table->VisibleMaskByIndex.TestBit(column_n))
|
||||
return;
|
||||
if (table->RowCellDataCurrent < 0 || table->RowCellData[table->RowCellDataCurrent].Column != column_n)
|
||||
table->RowCellDataCurrent++;
|
||||
|
@ -1920,7 +1920,7 @@ bool ImGui::TableSetColumnIndex(int column_n)
|
|||
|
||||
// Return whether the column is visible. User may choose to skip submitting items based on this return value,
|
||||
// however they shouldn't skip submitting for columns that may have the tallest contribution to row height.
|
||||
return (table->RequestOutputMaskByIndex & column_n) != 0;
|
||||
return table->RequestOutputMaskByIndex.TestBit(column_n);
|
||||
}
|
||||
|
||||
// [Public] Append into the next column, wrap and create a new row when already on last column
|
||||
|
@ -1946,7 +1946,7 @@ bool ImGui::TableNextColumn()
|
|||
// Return whether the column is visible. User may choose to skip submitting items based on this return value,
|
||||
// however they shouldn't skip submitting for columns that may have the tallest contribution to row height.
|
||||
int column_n = table->CurrentColumn;
|
||||
return (table->RequestOutputMaskByIndex & column_n) != 0;
|
||||
return table->RequestOutputMaskByIndex.TestBit(column_n);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1998,11 +1998,6 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
|
|||
{
|
||||
// FIXME-TABLE: Could avoid this if draw channel is dummy channel?
|
||||
SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
|
||||
if (column->DrawChannelCurrent==(ImGuiTableDrawChannelIdx)-1) {
|
||||
// temporary workaround for #502
|
||||
//printf("sorry!\n");
|
||||
column->DrawChannelCurrent=column_n;
|
||||
}
|
||||
table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
|
||||
}
|
||||
|
||||
|
@ -2380,7 +2375,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
|||
// 1. Scan channels and take note of those which can be merged
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
{
|
||||
if ((table->VisibleMaskByIndex & column_n) == 0)
|
||||
if (!table->VisibleMaskByIndex.TestBit(column_n))
|
||||
continue;
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
|
||||
|
@ -2544,7 +2539,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
|
|||
{
|
||||
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
|
||||
{
|
||||
if (!(table->EnabledMaskByDisplayOrder & order_n))
|
||||
if (!table->EnabledMaskByDisplayOrder.TestBit(order_n))
|
||||
continue;
|
||||
|
||||
const int column_n = table->DisplayOrderToIndex[order_n];
|
||||
|
|
|
@ -2160,6 +2160,7 @@ void DivEngine::delSample(int index) {
|
|||
void DivEngine::addOrder(bool duplicate, bool where) {
|
||||
unsigned char order[DIV_MAX_CHANS];
|
||||
if (curSubSong->ordersLen>=0xff) return;
|
||||
memset(order,0,DIV_MAX_CHANS);
|
||||
BUSY_BEGIN_SOFT;
|
||||
if (duplicate) {
|
||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
|
@ -2986,6 +2987,9 @@ bool DivEngine::init() {
|
|||
oscBuf[0]=new float[32768];
|
||||
oscBuf[1]=new float[32768];
|
||||
|
||||
memset(oscBuf[0],0,32768*sizeof(float));
|
||||
memset(oscBuf[1],0,32768*sizeof(float));
|
||||
|
||||
initDispatch();
|
||||
renderSamples();
|
||||
reset();
|
||||
|
|
|
@ -61,6 +61,7 @@ enum DivInstrumentType: unsigned short {
|
|||
DIV_INS_SNES=29,
|
||||
DIV_INS_SU=30,
|
||||
DIV_INS_NAMCO=31,
|
||||
DIV_INS_OPL_DRUMS=32,
|
||||
DIV_INS_MAX,
|
||||
DIV_INS_NULL
|
||||
};
|
||||
|
|
|
@ -179,6 +179,11 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) {
|
|||
rWrite(0x22,lfoValue);
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_FM_FB: {
|
||||
chan[2].state.fb=c.value&7;
|
||||
rWrite(chanOffs[2]+ADDR_FB_ALG,(chan[2].state.alg&7)|(chan[2].state.fb<<3));
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_FM_MULT: { // TODO
|
||||
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||
|
|
|
@ -155,6 +155,11 @@ int DivPlatformYM2203Ext::dispatch(DivCommand c) {
|
|||
rWrite(0x22,(c.value&7)|((c.value>>4)<<3));
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_FM_FB: {
|
||||
chan[2].state.fb=c.value&7;
|
||||
rWrite(chanOffs[2]+ADDR_FB_ALG,(chan[2].state.alg&7)|(chan[2].state.fb<<3));
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_FM_MULT: { // TODO
|
||||
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
||||
|
|
|
@ -155,6 +155,11 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) {
|
|||
rWrite(0x22,(c.value&7)|((c.value>>4)<<3));
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_FM_FB: {
|
||||
chan[2].state.fb=c.value&7;
|
||||
rWrite(chanOffs[2]+ADDR_FB_ALG,(chan[2].state.alg&7)|(chan[2].state.fb<<3));
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_FM_MULT: { // TODO
|
||||
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
||||
|
|
|
@ -155,6 +155,11 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) {
|
|||
rWrite(0x22,(c.value&7)|((c.value>>4)<<3));
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_FM_FB: {
|
||||
chan[2].state.fb=c.value&7;
|
||||
rWrite(chanOffs[2]+ADDR_FB_ALG,(chan[2].state.alg&7)|(chan[2].state.fb<<3));
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_FM_MULT: { // TODO
|
||||
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
||||
|
|
|
@ -155,6 +155,11 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) {
|
|||
rWrite(0x22,(c.value&7)|((c.value>>4)<<3));
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_FM_FB: {
|
||||
chan[1].state.fb=c.value&7;
|
||||
rWrite(chanOffs[1]+ADDR_FB_ALG,(chan[1].state.alg&7)|(chan[1].state.fb<<3));
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_FM_MULT: { // TODO
|
||||
unsigned short baseAddr=chanOffs[1]|opOffs[orderedOps[c.value]];
|
||||
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
||||
|
|
|
@ -409,7 +409,7 @@ struct DivSong {
|
|||
|
||||
std::vector<DivSubSong*> subsong;
|
||||
|
||||
DivInstrument nullIns, nullInsOPLL, nullInsOPL, nullInsQSound;
|
||||
DivInstrument nullIns, nullInsOPLL, nullInsOPL, nullInsOPLDrums, nullInsQSound;
|
||||
DivWavetable nullWave;
|
||||
DivSample nullSample;
|
||||
|
||||
|
@ -552,6 +552,9 @@ struct DivSong {
|
|||
nullInsOPL.fm.op[1].rr=12;
|
||||
nullInsOPL.fm.op[1].mult=1;
|
||||
nullInsOPL.name="This is a bug! Report!";
|
||||
nullInsOPL.fm.kickFreq=0x520;
|
||||
nullInsOPL.fm.snareHatFreq=0x550;
|
||||
nullInsOPL.fm.tomTopFreq=0x1c0;
|
||||
|
||||
nullInsQSound.std.panLMacro.mode=true;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "dispatch.h"
|
||||
#include "engine.h"
|
||||
#include "instrument.h"
|
||||
#include "song.h"
|
||||
#include "../ta-log.h"
|
||||
|
||||
|
@ -1579,11 +1580,11 @@ void DivEngine::registerSystems() {
|
|||
sysDefs[DIV_SYSTEM_OPL_DRUMS]=new DivSysDef(
|
||||
"Yamaha YM3526 (OPL) with drums", NULL, 0xa2, 0, 11, true, false, 0x151, false,
|
||||
"the OPL chip but with drums mode enabled.",
|
||||
{"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Kick", "Snare", "Tom", "Top", "HiHat"},
|
||||
{"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Kick/FM 7", "Snare", "Tom", "Top", "HiHat"},
|
||||
{"F1", "F2", "F3", "F4", "F5", "F6", "BD", "SD", "TM", "TP", "HH"},
|
||||
{DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE},
|
||||
{DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL},
|
||||
{},
|
||||
{DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS},
|
||||
{DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL},
|
||||
oplDrumsEffectHandler,
|
||||
fmOPLPostEffectHandler
|
||||
);
|
||||
|
@ -1591,11 +1592,11 @@ void DivEngine::registerSystems() {
|
|||
sysDefs[DIV_SYSTEM_OPL2_DRUMS]=new DivSysDef(
|
||||
"Yamaha YM3812 (OPL2) with drums", NULL, 0xa3, 0, 11, true, false, 0x151, false,
|
||||
"the OPL2 chip but with drums mode enabled.",
|
||||
{"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Kick", "Snare", "Tom", "Top", "HiHat"},
|
||||
{"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Kick/FM 7", "Snare", "Tom", "Top", "HiHat"},
|
||||
{"F1", "F2", "F3", "F4", "F5", "F6", "BD", "SD", "TM", "TP", "HH"},
|
||||
{DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE},
|
||||
{DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL},
|
||||
{},
|
||||
{DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS},
|
||||
{DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL},
|
||||
oplDrumsEffectHandler,
|
||||
fmOPLPostEffectHandler
|
||||
);
|
||||
|
@ -1603,11 +1604,11 @@ void DivEngine::registerSystems() {
|
|||
sysDefs[DIV_SYSTEM_OPL3_DRUMS]=new DivSysDef(
|
||||
"Yamaha YMF262 (OPL3) with drums", NULL, 0xa4, 0, 20, true, false, 0x151, false,
|
||||
"the OPL3 chip but with drums mode enabled.",
|
||||
{"4OP 1", "FM 2", "4OP 3", "FM 4", "4OP 5", "FM 6", "4OP 7", "FM 8", "4OP 9", "FM 10", "4OP 11", "FM 12", "FM 13", "FM 14", "FM 15", "Kick", "Snare", "Tom", "Top", "HiHat"},
|
||||
{"4OP 1", "FM 2", "4OP 3", "FM 4", "4OP 5", "FM 6", "4OP 7", "FM 8", "4OP 9", "FM 10", "4OP 11", "FM 12", "FM 13", "FM 14", "FM 15", "Kick/FM 16", "Snare", "Tom", "Top", "HiHat"},
|
||||
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "BD", "SD", "TM", "TP", "HH"},
|
||||
{DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE},
|
||||
{DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL},
|
||||
{},
|
||||
{DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS},
|
||||
{DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL},
|
||||
oplDrumsEffectHandler,
|
||||
fmOPLPostEffectHandler
|
||||
);
|
||||
|
@ -1820,7 +1821,7 @@ void DivEngine::registerSystems() {
|
|||
sysDefs[DIV_SYSTEM_OPL4_DRUMS]=new DivSysDef(
|
||||
"Yamaha OPL4 with drums", NULL, 0xaf, 0, 44, true, true, 0, false,
|
||||
"the OPL4 but with drums mode turned on.",
|
||||
{"4OP 1", "FM 2", "4OP 3", "FM 4", "4OP 5", "FM 6", "4OP 7", "FM 8", "4OP 9", "FM 10", "4OP 11", "FM 12", "FM 13", "FM 14", "FM 15", "Kick", "Snare", "Tom", "Top", "HiHat", "PCM 1", "PCM 2", "PCM 3", "PCM 4", "PCM 5", "PCM 6", "PCM 7", "PCM 8", "PCM 9", "PCM 10", "PCM 11", "PCM 12", "PCM 13", "PCM 14", "PCM 15", "PCM 16", "PCM 17", "PCM 18", "PCM 19", "PCM 20", "PCM 21", "PCM 22", "PCM 23", "PCM 24"},
|
||||
{"4OP 1", "FM 2", "4OP 3", "FM 4", "4OP 5", "FM 6", "4OP 7", "FM 8", "4OP 9", "FM 10", "4OP 11", "FM 12", "FM 13", "FM 14", "FM 15", "Kick/FM 16", "Snare", "Tom", "Top", "HiHat", "PCM 1", "PCM 2", "PCM 3", "PCM 4", "PCM 5", "PCM 6", "PCM 7", "PCM 8", "PCM 9", "PCM 10", "PCM 11", "PCM 12", "PCM 13", "PCM 14", "PCM 15", "PCM 16", "PCM 17", "PCM 18", "PCM 19", "PCM 20", "PCM 21", "PCM 22", "PCM 23", "PCM 24"},
|
||||
{"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15", "BD", "SD", "TM", "TP", "HH", "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P8", "P10", "P11", "P12", "P13", "P14", "P15", "P16", "P17", "P18", "P19", "P20", "P21", "P22", "P23", "P24"},
|
||||
{DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
||||
{DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM}
|
||||
|
@ -1928,11 +1929,11 @@ void DivEngine::registerSystems() {
|
|||
sysDefs[DIV_SYSTEM_Y8950_DRUMS]=new DivSysDef(
|
||||
"Yamaha Y8950 with drums", NULL, 0xb3, 0, 12, true, false, 0x151, false,
|
||||
"the Y8950 chip, in drums mode.",
|
||||
{"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Kick", "Snare", "Tom", "Top", "HiHat", "PCM"},
|
||||
{"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Kick/FM 7", "Snare", "Tom", "Top", "HiHat", "PCM"},
|
||||
{"F1", "F2", "F3", "F4", "F5", "F6", "BD", "SD", "TM", "TP", "HH", "PCM"},
|
||||
{DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_PCM},
|
||||
{DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_AMIGA},
|
||||
{},
|
||||
{DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_OPL_DRUMS, DIV_INS_AMIGA},
|
||||
{DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_NULL},
|
||||
oplEffectHandler,
|
||||
fmOPLPostEffectHandler
|
||||
);
|
||||
|
|
|
@ -27,6 +27,21 @@ void FurnaceGUI::startSelection(int xCoarse, int xFine, int y, bool fullRow) {
|
|||
if (xCoarse!=selStart.xCoarse || xFine!=selStart.xFine || y!=selStart.y) {
|
||||
curNibble=false;
|
||||
}
|
||||
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) && !fullRow && settings.doubleClickColumn) {
|
||||
if (cursor.xCoarse==xCoarse && cursor.xFine==xFine && cursor.y==y) {
|
||||
// select entire channel
|
||||
selStart.xCoarse=xCoarse;
|
||||
selStart.xFine=0;
|
||||
selStart.y=0;
|
||||
selEnd.xCoarse=xCoarse;
|
||||
selEnd.xFine=2+e->curPat[selEnd.xCoarse].effectCols*2;
|
||||
selEnd.y=e->curSubSong->patLen-1;
|
||||
|
||||
finishSelection();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (fullRow) {
|
||||
selStart.xCoarse=firstChannel;
|
||||
|
@ -314,4 +329,4 @@ void FurnaceGUI::editAdvance() {
|
|||
selStart=cursor;
|
||||
selEnd=cursor;
|
||||
updateScroll(cursor.y);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -313,6 +313,10 @@ void FurnaceGUI::drawInsList() {
|
|||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_NAMCO]);
|
||||
name=fmt::sprintf(ICON_FA_PIE_CHART " %.2X: %s##_INS%d",i,ins->name,i);
|
||||
break;
|
||||
case DIV_INS_OPL_DRUMS:
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_OPL_DRUMS]);
|
||||
name=fmt::sprintf(ICON_FA_COFFEE " %.2X: %s##_INS%d",i,ins->name,i);
|
||||
break;
|
||||
default:
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_UNKNOWN]);
|
||||
name=fmt::sprintf(ICON_FA_QUESTION " %.2X: %s##_INS%d",i,ins->name,i);
|
||||
|
|
|
@ -3927,6 +3927,9 @@ bool FurnaceGUI::init() {
|
|||
if (orderEditMode<0) orderEditMode=0;
|
||||
if (orderEditMode>3) orderEditMode=3;
|
||||
|
||||
oscZoom=e->getConfFloat("oscZoom",0.5f);
|
||||
oscWindowSize=e->getConfFloat("oscWindowSize",20.0f);
|
||||
|
||||
pianoOctaves=e->getConfInt("pianoOctaves",pianoOctaves);
|
||||
pianoOctavesEdit=e->getConfInt("pianoOctavesEdit",pianoOctavesEdit);
|
||||
pianoOptions=e->getConfBool("pianoOptions",pianoOptions);
|
||||
|
@ -4137,6 +4140,10 @@ bool FurnaceGUI::finish() {
|
|||
e->setConf("followPattern",followPattern);
|
||||
e->setConf("orderEditMode",orderEditMode);
|
||||
|
||||
// commit oscilloscope state
|
||||
e->setConf("oscZoom",oscZoom);
|
||||
e->setConf("oscWindowSize",oscWindowSize);
|
||||
|
||||
// commit piano state
|
||||
e->setConf("pianoOctaves",pianoOctaves);
|
||||
e->setConf("pianoOctavesEdit",pianoOctavesEdit);
|
||||
|
@ -4422,6 +4429,7 @@ FurnaceGUI::FurnaceGUI():
|
|||
openSampleFilterOpt(false),
|
||||
oscTotal(0),
|
||||
oscZoom(0.5f),
|
||||
oscWindowSize(20.0f),
|
||||
oscZoomSlider(false),
|
||||
chanOscCols(3),
|
||||
chanOscWindowSize(20.0f),
|
||||
|
|
|
@ -151,6 +151,7 @@ enum FurnaceGUIColors {
|
|||
GUI_COLOR_INSTR_SNES,
|
||||
GUI_COLOR_INSTR_SU,
|
||||
GUI_COLOR_INSTR_NAMCO,
|
||||
GUI_COLOR_INSTR_OPL_DRUMS,
|
||||
GUI_COLOR_INSTR_UNKNOWN,
|
||||
|
||||
GUI_COLOR_CHANNEL_FM,
|
||||
|
@ -950,6 +951,7 @@ class FurnaceGUI {
|
|||
int volCellSpacing;
|
||||
int effectCellSpacing;
|
||||
int effectValCellSpacing;
|
||||
int doubleClickColumn;
|
||||
unsigned int maxUndoSteps;
|
||||
String mainFontPath;
|
||||
String patFontPath;
|
||||
|
@ -1048,6 +1050,7 @@ class FurnaceGUI {
|
|||
volCellSpacing(0),
|
||||
effectCellSpacing(0),
|
||||
effectValCellSpacing(0),
|
||||
doubleClickColumn(1),
|
||||
maxUndoSteps(100),
|
||||
mainFontPath(""),
|
||||
patFontPath(""),
|
||||
|
@ -1238,6 +1241,7 @@ class FurnaceGUI {
|
|||
int oscTotal;
|
||||
float oscValues[512];
|
||||
float oscZoom;
|
||||
float oscWindowSize;
|
||||
bool oscZoomSlider;
|
||||
|
||||
// per-channel oscilloscope
|
||||
|
|
|
@ -112,6 +112,7 @@ const char* insTypes[DIV_INS_MAX+1]={
|
|||
"SNES",
|
||||
"Sound Unit",
|
||||
"Namco WSG",
|
||||
"OPL (drums)",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -765,6 +766,7 @@ const FurnaceGUIColorDef guiColors[GUI_COLOR_MAX]={
|
|||
D(GUI_COLOR_INSTR_SNES,"",ImVec4(0.8f,0.7f,1.0f,1.0f)),
|
||||
D(GUI_COLOR_INSTR_SU,"",ImVec4(0.95f,0.98f,1.0f,1.0f)),
|
||||
D(GUI_COLOR_INSTR_NAMCO,"",ImVec4(1.0f,1.0f,0.0f,1.0f)),
|
||||
D(GUI_COLOR_INSTR_OPL_DRUMS,"",ImVec4(0.3f,1.0f,0.9f,1.0f)),
|
||||
D(GUI_COLOR_INSTR_UNKNOWN,"",ImVec4(0.3f,0.3f,0.3f,1.0f)),
|
||||
|
||||
D(GUI_COLOR_CHANNEL_FM,"",ImVec4(0.2f,0.8f,1.0f,1.0f)),
|
||||
|
|
|
@ -75,6 +75,10 @@ const char* opzWaveforms[8]={
|
|||
"Sine", "Triangle", "Cut Sine", "Cut Triangle", "Squished Sine", "Squished Triangle", "Squished AbsSine", "Squished AbsTriangle"
|
||||
};
|
||||
|
||||
const char* oplDrumNames[4]={
|
||||
"Snare", "Tom", "Top", "HiHat"
|
||||
};
|
||||
|
||||
const bool opIsOutput[8][4]={
|
||||
{false,false,false,true},
|
||||
{false,false,false,true},
|
||||
|
@ -1537,7 +1541,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
|
||||
if (ImGui::BeginTabBar("insEditTab")) {
|
||||
std::vector<FurnaceGUIMacroDesc> macroList;
|
||||
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPZ) {
|
||||
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPL_DRUMS) {
|
||||
char label[32];
|
||||
int opCount=4;
|
||||
if (ins->type==DIV_INS_OPLL) opCount=2;
|
||||
|
@ -1579,22 +1583,27 @@ void FurnaceGUI::drawInsEdit() {
|
|||
showError("Coming soon!");
|
||||
}
|
||||
break;
|
||||
case DIV_INS_OPL: {
|
||||
bool fourOp=(ins->fm.ops==4);
|
||||
case DIV_INS_OPL:
|
||||
case DIV_INS_OPL_DRUMS: {
|
||||
bool fourOp=(ins->fm.ops==4 || ins->type==DIV_INS_OPL_DRUMS);
|
||||
bool drums=ins->fm.opllPreset==16;
|
||||
int algMax=fourOp?3:1;
|
||||
ImGui::TableNextColumn();
|
||||
ins->fm.alg&=algMax;
|
||||
P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable
|
||||
ImGui::BeginDisabled(ins->fm.opllPreset==16);
|
||||
if (ImGui::Checkbox("4-op",&fourOp)) { PARAMETER
|
||||
ins->fm.ops=fourOp?4:2;
|
||||
if (ins->type==DIV_INS_OPL) {
|
||||
ImGui::BeginDisabled(ins->fm.opllPreset==16);
|
||||
if (ImGui::Checkbox("4-op",&fourOp)) { PARAMETER
|
||||
ins->fm.ops=fourOp?4:2;
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::TableNextColumn();
|
||||
P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&algMax)); rightClickable
|
||||
if (ImGui::Checkbox("Drums",&drums)) { PARAMETER
|
||||
ins->fm.opllPreset=drums?16:0;
|
||||
if (ins->type==DIV_INS_OPL) {
|
||||
if (ImGui::Checkbox("Drums",&drums)) { PARAMETER
|
||||
ins->fm.opllPreset=drums?16:0;
|
||||
}
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
drawAlgorithm(ins->fm.alg&algMax,fourOp?FM_ALGS_4OP_OPL:FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
|
||||
|
@ -1639,7 +1648,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if ((ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL) && ins->fm.opllPreset==16) {
|
||||
if (((ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL) && ins->fm.opllPreset==16) || ins->type==DIV_INS_OPL_DRUMS) {
|
||||
ins->fm.ops=2;
|
||||
P(ImGui::Checkbox("Fixed frequency mode",&ins->fm.fixedDrums));
|
||||
if (ImGui::IsItemHovered()) {
|
||||
|
@ -1674,7 +1683,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
if (willDisplayOps) {
|
||||
if (settings.fmLayout==0) {
|
||||
int numCols=16;
|
||||
if (ins->type==DIV_INS_OPL) numCols=13;
|
||||
if (ins->type==DIV_INS_OPL ||ins->type==DIV_INS_OPL_DRUMS) numCols=13;
|
||||
if (ins->type==DIV_INS_OPLL) numCols=12;
|
||||
if (ins->type==DIV_INS_OPZ) numCols=19;
|
||||
if (ImGui::BeginTable("FMOperators",numCols,ImGuiTableFlags_SizingStretchProp|ImGuiTableFlags_BordersH|ImGuiTableFlags_BordersOuterV)) {
|
||||
|
@ -1785,7 +1794,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
ImGui::TextUnformatted("Other");
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPZ) {
|
||||
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_NAME(FM_WS));
|
||||
ImGui::TextUnformatted(FM_NAME(FM_WS));
|
||||
|
@ -1801,14 +1810,16 @@ void FurnaceGUI::drawInsEdit() {
|
|||
float sliderHeight=32.0f*dpiScale;
|
||||
|
||||
for (int i=0; i<opCount; i++) {
|
||||
DivInstrumentFM::Operator& op=ins->fm.op[(opCount==4)?opOrder[i]:i];
|
||||
DivInstrumentFM::Operator& op=ins->fm.op[(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS)?opOrder[i]:i];
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
// push colors
|
||||
if (settings.separateFMColors) {
|
||||
bool mod=true;
|
||||
if (opCount==4) {
|
||||
if (ins->type==DIV_INS_OPL_DRUMS) {
|
||||
mod=false;
|
||||
} else if (opCount==4) {
|
||||
if (ins->type==DIV_INS_OPL) {
|
||||
if (opIsOutputOPL[ins->fm.alg&3][i]) mod=false;
|
||||
} else {
|
||||
|
@ -1837,7 +1848,9 @@ void FurnaceGUI::drawInsEdit() {
|
|||
if (i==0) sliderHeight=(ImGui::GetContentRegionAvail().y/opCount)-ImGui::GetStyle().ItemSpacing.y;
|
||||
|
||||
ImGui::PushID(fmt::sprintf("op%d",i).c_str());
|
||||
if (ins->type==DIV_INS_OPL && ins->fm.opllPreset==16) {
|
||||
if (ins->type==DIV_INS_OPL_DRUMS) {
|
||||
ImGui::Text("%s",oplDrumNames[i]);
|
||||
} else if (ins->type==DIV_INS_OPL && ins->fm.opllPreset==16) {
|
||||
if (i==1) {
|
||||
ImGui::Text("Kick");
|
||||
} else {
|
||||
|
@ -1855,7 +1868,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
maxTl=63;
|
||||
}
|
||||
}
|
||||
if (ins->type==DIV_INS_OPL) {
|
||||
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) {
|
||||
maxTl=63;
|
||||
}
|
||||
int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ)?31:15;
|
||||
|
@ -1989,7 +2002,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
}
|
||||
}
|
||||
|
||||
if (ins->type!=DIV_INS_OPL && ins->type!=DIV_INS_OPZ) {
|
||||
if (ins->type!=DIV_INS_OPL && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_OPZ) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale));
|
||||
ImGui::TableNextColumn();
|
||||
|
@ -2024,7 +2037,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER
|
||||
op.ksr=ksrOn;
|
||||
}
|
||||
if (ins->type==DIV_INS_OPL) {
|
||||
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) {
|
||||
if (ImGui::Checkbox(FM_NAME(FM_SUS),&susOn)) { PARAMETER
|
||||
op.sus=susOn;
|
||||
}
|
||||
|
@ -2035,7 +2048,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
}
|
||||
}
|
||||
|
||||
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPZ) {
|
||||
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale));
|
||||
ImGui::TableNextColumn();
|
||||
|
@ -2043,7 +2056,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight-ImGui::GetFrameHeightWithSpacing()));
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable
|
||||
if (ins->type==DIV_INS_OPL && ImGui::IsItemHovered()) {
|
||||
if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("OPL2/3 only (last 4 waveforms are OPL3 only)");
|
||||
}
|
||||
} else if (ins->type==DIV_INS_OPLL) {
|
||||
|
@ -2052,7 +2065,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,ins->fm.alg,maxTl,maxArDr,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight),ins->type);
|
||||
drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,ins->fm.alg,maxTl,maxArDr,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight),ins->type);
|
||||
|
||||
if (settings.separateFMColors) {
|
||||
popAccentColors();
|
||||
|
@ -2078,7 +2091,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
}
|
||||
if (ImGui::BeginTable("FMOperators",columns,ImGuiTableFlags_SizingStretchSame)) {
|
||||
for (int i=0; i<opCount; i++) {
|
||||
DivInstrumentFM::Operator& op=ins->fm.op[(opCount==4)?opOrder[i]:i];
|
||||
DivInstrumentFM::Operator& op=ins->fm.op[(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS)?opOrder[i]:i];
|
||||
if ((settings.fmLayout!=3 && ((i+1)&1)) || i==0 || settings.fmLayout==2) ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Separator();
|
||||
|
@ -2087,7 +2100,9 @@ void FurnaceGUI::drawInsEdit() {
|
|||
// push colors
|
||||
if (settings.separateFMColors) {
|
||||
bool mod=true;
|
||||
if (opCount==4) {
|
||||
if (ins->type==DIV_INS_OPL_DRUMS) {
|
||||
mod=false;
|
||||
} else if (opCount==4) {
|
||||
if (ins->type==DIV_INS_OPL) {
|
||||
if (opIsOutputOPL[ins->fm.alg&3][i]) mod=false;
|
||||
} else {
|
||||
|
@ -2114,7 +2129,9 @@ void FurnaceGUI::drawInsEdit() {
|
|||
}
|
||||
|
||||
ImGui::Dummy(ImVec2(dpiScale,dpiScale));
|
||||
if (ins->type==DIV_INS_OPL && ins->fm.opllPreset==16) {
|
||||
if (ins->type==DIV_INS_OPL_DRUMS) {
|
||||
ImGui::Text("%s",oplDrumNames[i]);
|
||||
} else if (ins->type==DIV_INS_OPL && ins->fm.opllPreset==16) {
|
||||
if (i==1) {
|
||||
ImGui::Text("Envelope 2 (kick only)");
|
||||
} else {
|
||||
|
@ -2139,7 +2156,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
maxTl=63;
|
||||
}
|
||||
}
|
||||
if (ins->type==DIV_INS_OPL) {
|
||||
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) {
|
||||
maxTl=63;
|
||||
}
|
||||
int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ)?31:15;
|
||||
|
@ -2149,7 +2166,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
bool vibOn=op.vib;
|
||||
bool susOn=op.sus; // don't you make fun of this one
|
||||
unsigned char ssgEnv=op.ssgEnv&7;
|
||||
if (ins->type!=DIV_INS_OPL && ins->type!=DIV_INS_OPZ) {
|
||||
if (ins->type!=DIV_INS_OPL && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_OPZ) {
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Checkbox((ins->type==DIV_INS_OPLL)?FM_NAME(FM_EGS):"SSG On",&ssgOn)) { PARAMETER
|
||||
op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3);
|
||||
|
@ -2161,7 +2178,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
}
|
||||
}
|
||||
|
||||
if (ins->type==DIV_INS_OPL) {
|
||||
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) {
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Checkbox(FM_NAME(FM_SUS),&susOn)) { PARAMETER
|
||||
op.sus=susOn;
|
||||
|
@ -2169,7 +2186,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
}
|
||||
|
||||
//52.0 controls vert scaling; default 96
|
||||
drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,ins->fm.alg,maxTl,maxArDr,ImVec2(ImGui::GetContentRegionAvail().x,52.0*dpiScale),ins->type);
|
||||
drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,ins->fm.alg,maxTl,maxArDr,ImVec2(ImGui::GetContentRegionAvail().x,52.0*dpiScale),ins->type);
|
||||
//P(CWSliderScalar(FM_NAME(FM_AR),ImGuiDataType_U8,&op.ar,&_ZERO,&_THIRTY_ONE)); rightClickable
|
||||
if (ImGui::BeginTable("opParams",2,ImGuiTableFlags_SizingStretchProp)) {
|
||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); \
|
||||
|
@ -2292,12 +2309,12 @@ void FurnaceGUI::drawInsEdit() {
|
|||
}
|
||||
}
|
||||
|
||||
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPZ) {
|
||||
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable
|
||||
if (ins->type==DIV_INS_OPL && ImGui::IsItemHovered()) {
|
||||
if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("OPL2/3 only (last 4 waveforms are OPL3 only)");
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
|
@ -2307,7 +2324,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if (ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL) {
|
||||
if (ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) {
|
||||
if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER
|
||||
op.vib=vibOn;
|
||||
}
|
||||
|
@ -2338,7 +2355,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
} else {
|
||||
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_ALG),&ins->std.algMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER]));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FB),&ins->std.fbMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER]));
|
||||
if (ins->type!=DIV_INS_OPL) {
|
||||
if (ins->type!=DIV_INS_OPL && ins->type!=DIV_INS_OPL_DRUMS) {
|
||||
if (ins->type==DIV_INS_OPZ) {
|
||||
// TODO: FMS2/AMS2 macros
|
||||
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FMS),&ins->std.fmsMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER]));
|
||||
|
@ -2361,7 +2378,11 @@ void FurnaceGUI::drawInsEdit() {
|
|||
ImGui::EndTabItem();
|
||||
}
|
||||
for (int i=0; i<opCount; i++) {
|
||||
snprintf(label,31,"OP%d Macros",i+1);
|
||||
if (ins->type==DIV_INS_OPL_DRUMS) {
|
||||
snprintf(label,31,"%s Macros",oplDrumNames[i]);
|
||||
} else {
|
||||
snprintf(label,31,"OP%d Macros",i+1);
|
||||
}
|
||||
if (ImGui::BeginTabItem(label)) {
|
||||
ImGui::PushID(i);
|
||||
int ordi=(opCount==4)?orderedOps[i]:i;
|
||||
|
@ -2373,12 +2394,12 @@ void FurnaceGUI::drawInsEdit() {
|
|||
maxTl=63;
|
||||
}
|
||||
}
|
||||
if (ins->type==DIV_INS_OPL) {
|
||||
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) {
|
||||
maxTl=63;
|
||||
}
|
||||
int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ)?31:15;
|
||||
|
||||
if (ins->type==DIV_INS_OPL) {
|
||||
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) {
|
||||
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_TL),&ins->std.opMacros[ordi].tlMacro,0,maxTl,128,uiColors[GUI_COLOR_MACRO_OTHER]));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AR),&ins->std.opMacros[ordi].arMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_OTHER]));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DR),&ins->std.opMacros[ordi].drMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_OTHER]));
|
||||
|
|
|
@ -21,9 +21,6 @@
|
|||
#include "imgui_internal.h"
|
||||
#include <imgui.h>
|
||||
|
||||
// TODO:
|
||||
// - potentially move oscilloscope seek position to the end, and read the last samples
|
||||
// - this allows for setting up the window size
|
||||
void FurnaceGUI::readOsc() {
|
||||
int writePos=e->oscWritePos;
|
||||
int readPos=e->oscReadPos;
|
||||
|
@ -47,8 +44,11 @@ void FurnaceGUI::readOsc() {
|
|||
total=oscTotal+(bias>>6);
|
||||
if (total>avail) total=avail;
|
||||
//printf("total: %d. avail: %d bias: %d\n",total,avail,bias);
|
||||
|
||||
int winSize=e->getAudioDescGot().rate*(oscWindowSize/1000.0);
|
||||
int oscReadPos=(writePos-winSize)&0x7fff;
|
||||
for (int i=0; i<512; i++) {
|
||||
int pos=(readPos+(i*total/512))&0x7fff;
|
||||
int pos=(oscReadPos+(i*winSize/512))&0x7fff;
|
||||
oscValues[i]=(e->oscBuf[0][pos]+e->oscBuf[1][pos])*0.5f;
|
||||
if (oscValues[i]>0.001f || oscValues[i]<-0.001f) {
|
||||
WAKE_UP;
|
||||
|
@ -97,6 +97,14 @@ void FurnaceGUI::drawOsc() {
|
|||
if (oscZoom>2.0) oscZoom=2.0;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::VSliderFloat("##OscWinSize",ImVec2(20.0f*dpiScale,ImGui::GetContentRegionAvail().y),&oscWindowSize,5.0,100.0)) {
|
||||
if (oscWindowSize<5.0) oscWindowSize=5.0;
|
||||
if (oscWindowSize>100.0) oscWindowSize=100.0;
|
||||
}
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Middle)) {
|
||||
oscWindowSize=20.0;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
ImDrawList* dl=ImGui::GetWindowDrawList();
|
||||
|
|
|
@ -404,6 +404,11 @@ void FurnaceGUI::drawSettings() {
|
|||
settings.cursorMoveNoScroll=cursorMoveNoScrollB;
|
||||
}
|
||||
|
||||
bool doubleClickColumnB=settings.doubleClickColumn;
|
||||
if (ImGui::Checkbox("Double click selects entire column",&doubleClickColumnB)) {
|
||||
settings.doubleClickColumn=doubleClickColumnB;
|
||||
}
|
||||
|
||||
bool allowEditDockingB=settings.allowEditDocking;
|
||||
if (ImGui::Checkbox("Allow docking editors",&allowEditDockingB)) {
|
||||
settings.allowEditDocking=allowEditDockingB;
|
||||
|
@ -2009,7 +2014,7 @@ void FurnaceGUI::syncSettings() {
|
|||
settings.insCellSpacing=e->getConfInt("insCellSpacing",0);
|
||||
settings.volCellSpacing=e->getConfInt("volCellSpacing",0);
|
||||
settings.effectCellSpacing=e->getConfInt("effectCellSpacing",0);
|
||||
settings.effectValCellSpacing=e->getConfInt("effectValCellSpacing",0);
|
||||
settings.doubleClickColumn=e->getConfInt("doubleClickColumn",0);
|
||||
|
||||
clampSetting(settings.mainFontSize,2,96);
|
||||
clampSetting(settings.patFontSize,2,96);
|
||||
|
@ -2092,6 +2097,7 @@ void FurnaceGUI::syncSettings() {
|
|||
clampSetting(settings.volCellSpacing,0,32);
|
||||
clampSetting(settings.effectCellSpacing,0,32);
|
||||
clampSetting(settings.effectValCellSpacing,0,32);
|
||||
clampSetting(settings.doubleClickColumn,0,1);
|
||||
|
||||
settings.initialSys=e->decodeSysDesc(e->getConfString("initialSys",""));
|
||||
if (settings.initialSys.size()<4) {
|
||||
|
@ -2223,6 +2229,7 @@ void FurnaceGUI::commitSettings() {
|
|||
e->setConf("volCellSpacing",settings.volCellSpacing);
|
||||
e->setConf("effectCellSpacing",settings.effectCellSpacing);
|
||||
e->setConf("effectValCellSpacing",settings.effectValCellSpacing);
|
||||
e->setConf("doubleClickColumn",settings.doubleClickColumn);
|
||||
|
||||
// colors
|
||||
for (int i=0; i<GUI_COLOR_MAX; i++) {
|
||||
|
|
Loading…
Reference in a new issue