Merge branch 'tildearrow:master' into master

This commit is contained in:
Waldemar Pawlaszek 2022-05-27 08:11:32 +02:00 committed by GitHub
commit 65817f7589
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 199 additions and 75 deletions

View File

@ -266,7 +266,7 @@ void YMPSG_Init(ympsg_t *chip, uint8_t real_sn)
chip->noise_size = real_sn ? 16383 : 32767; chip->noise_size = real_sn ? 16383 : 32767;
for (i = 0; i < 17; i++) for (i = 0; i < 17; i++)
{ {
chip->vol_table[i]=real_sn?tipsg_vol[i]:ympsg_vol[i]; chip->vol_table[i]=(real_sn?tipsg_vol[i]:ympsg_vol[i]) * 8192.0f;
} }
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
{ {
@ -315,15 +315,15 @@ void YMPSG_Clock(ympsg_t *chip)
} }
} }
float YMPSG_GetOutput(ympsg_t *chip) int YMPSG_GetOutput(ympsg_t *chip)
{ {
float sample = 0.f; int sample = 0;
uint32_t i; uint32_t i;
YMPSG_UpdateSample(chip); YMPSG_UpdateSample(chip);
if (chip->test & 1) if (chip->test & 1)
{ {
sample += chip->vol_table[chip->volume_out[chip->test >> 1]]; sample += chip->vol_table[chip->volume_out[chip->test >> 1]];
sample += chip->vol_table[16] * 3.f; sample += chip->vol_table[16] * 3;
} }
else if (!chip->mute) else if (!chip->mute)
{ {

View File

@ -59,7 +59,7 @@ typedef struct {
ympsg_writebuf writebuf[YMPSG_WRITEBUF_SIZE]; ympsg_writebuf writebuf[YMPSG_WRITEBUF_SIZE];
// //
float vol_table[17]; short vol_table[17];
uint8_t mute; uint8_t mute;
@ -71,7 +71,7 @@ uint16_t YMPSG_Read(ympsg_t *chip);
void YMPSG_Init(ympsg_t *chip, uint8_t real_sn); void YMPSG_Init(ympsg_t *chip, uint8_t real_sn);
void YMPSG_SetIC(ympsg_t *chip, uint32_t ic); void YMPSG_SetIC(ympsg_t *chip, uint32_t ic);
void YMPSG_Clock(ympsg_t *chip); void YMPSG_Clock(ympsg_t *chip);
float YMPSG_GetOutput(ympsg_t *chip); int YMPSG_GetOutput(ympsg_t *chip);
void YMPSG_Test(ympsg_t *chip, uint16_t test); void YMPSG_Test(ympsg_t *chip, uint16_t test);

View File

@ -559,14 +559,44 @@ template<int BITCOUNT, int OFFSET = 0>
struct ImBitArray struct ImBitArray
{ {
ImU32 Storage[(BITCOUNT + 31) >> 5]; ImU32 Storage[(BITCOUNT + 31) >> 5];
ImBitArray() { ClearAllBits(); } ImBitArray() { ClearAllBits(); }
void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); } void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); }
void SetAllBits() { memset(Storage, 255, sizeof(Storage)); } void SetAllBits() { memset(Storage, 255, sizeof(Storage)); }
bool TestBit(int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return ImBitArrayTestBit(Storage, n); } bool TestBit(int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return ImBitArrayTestBit(Storage, n); }
void SetBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArraySetBit(Storage, n); } 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 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) 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); } 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==(ImBitArray const &a) const
{
for (int i = 0; i < ((BITCOUNT + 31) >> 5); ++i)
if (Storage[i] != a.Storage[i])
return false;
return true;
}
bool operator!=(ImBitArray const &a) const
{
for (int i = 0; i < ((BITCOUNT + 31) >> 5); ++i)
if (Storage[i] == a.Storage[i])
return false;
return true;
}
template<int DSTBITCOUNT> bool operator==(ImBitArray<DSTBITCOUNT> const &a) const
{
for (int i = 0; i < ImMin((DSTBITCOUNT + 31) >> 5, (BITCOUNT + 31) >> 5); ++i)
if (Storage[i] != a.Storage[i])
return false;
return true;
}
template<int DSTBITCOUNT> bool operator!=(ImBitArray<DSTBITCOUNT> const &a) const
{
for (int i = 0; i < ImMin((DSTBITCOUNT + 31) >> 5, (BITCOUNT + 31) >> 5); ++i)
if (Storage[i] == a.Storage[i])
return false;
return true;
}
}; };
// Helper: ImBitVector // Helper: ImBitVector
@ -574,11 +604,33 @@ struct ImBitArray
struct IMGUI_API ImBitVector struct IMGUI_API ImBitVector
{ {
ImVector<ImU32> Storage; ImVector<ImU32> Storage;
void Create(int sz) { Storage.resize((sz + 31) >> 5); memset(Storage.Data, 0, (size_t)Storage.Size * sizeof(Storage.Data[0])); } int BitCount = 0;
void Clear() { Storage.clear(); } ImBitVector(int sz = 0) { if (sz > 0) { Create(sz); } }
bool TestBit(int n) const { IM_ASSERT(n < (Storage.Size << 5)); return ImBitArrayTestBit(Storage.Data, n); } void Create(int sz) { BitCount = sz; Storage.resize((sz + 31) >> 5); memset(Storage.Data, 0, (size_t)Storage.Size * sizeof(Storage.Data[0])); }
void SetBit(int n) { IM_ASSERT(n < (Storage.Size << 5)); ImBitArraySetBit(Storage.Data, n); } void Clear() { Storage.clear(); }
void ClearBit(int n) { IM_ASSERT(n < (Storage.Size << 5)); ImBitArrayClearBit(Storage.Data, n); } void ClearAllBits() { IM_ASSERT(Storage.Size > 0); memset(Storage.Data, 0, (size_t)Storage.Size * sizeof(Storage.Data[0])); }
void SetAllBits() { IM_ASSERT(Storage.Size > 0); memset(Storage.Data, 255, (size_t)Storage.Size * sizeof(Storage.Data[0])); }
bool TestBit(int n) const { IM_ASSERT(n >= 0 && n < BitCount); return ImBitArrayTestBit(Storage.Data, n); }
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
{
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;
}
}; };
// Helper: ImSpan<> // Helper: ImSpan<>
@ -2447,13 +2499,12 @@ struct IMGUI_API ImGuiTabBar
// [SECTION] Table support // [SECTION] Table support
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#define IM_COL32_DISABLE IM_COL32(0,0,0,1) // Special sentinel code which cannot be used as a regular color. #define IM_COL32_DISABLE IM_COL32(0,0,0,1) // Special sentinel code which cannot be used as a regular color.
#define IMGUI_TABLE_MAX_COLUMNS 64 // sizeof(ImU64) * 8. This is solely because we frequently encode columns set in a ImU64. #define IMGUI_TABLE_DRAW_CHANNELS(c) (4 + (c) * 2) // See TableSetupDrawChannels()
#define IMGUI_TABLE_MAX_DRAW_CHANNELS (4 + 64 * 2) // See TableSetupDrawChannels()
// Our current column maximum is 64 but we may raise that in the future. // Our current column maximum is IMGUI_TABLE_MAX_COLUMNS but we may raise that in the future.
typedef ImS8 ImGuiTableColumnIdx; typedef ImS32 ImGuiTableColumnIdx;
typedef ImU8 ImGuiTableDrawChannelIdx; typedef ImU32 ImGuiTableDrawChannelIdx;
// [Internal] sizeof() ~ 104 // [Internal] sizeof() ~ 104
// We use the terminology "Enabled" to refer to a column that is not Hidden by user/api. // We use the terminology "Enabled" to refer to a column that is not Hidden by user/api.
@ -2543,10 +2594,10 @@ struct IMGUI_API ImGuiTable
ImSpan<ImGuiTableColumn> Columns; // Point within RawData[] ImSpan<ImGuiTableColumn> Columns; // Point within RawData[]
ImSpan<ImGuiTableColumnIdx> DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1) ImSpan<ImGuiTableColumnIdx> DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1)
ImSpan<ImGuiTableCellData> RowCellData; // Point within RawData[]. Store cells background requests for current row. ImSpan<ImGuiTableCellData> RowCellData; // Point within RawData[]. Store cells background requests for current row.
ImU64 EnabledMaskByDisplayOrder; // Column DisplayOrder -> IsEnabled map ImBitVector EnabledMaskByDisplayOrder; // Column DisplayOrder -> IsEnabled map
ImU64 EnabledMaskByIndex; // Column Index -> IsEnabled map (== not hidden by user/api) in a format adequate for iterating column without touching cold data ImBitVector EnabledMaskByIndex; // Column Index -> IsEnabled map (== not hidden by user/api) in a format adequate for iterating column without touching cold data
ImU64 VisibleMaskByIndex; // Column Index -> IsVisibleX|IsVisibleY map (== not hidden by user/api && not hidden by scrolling/cliprect) ImBitVector VisibleMaskByIndex; // Column Index -> IsVisibleX|IsVisibleY map (== not hidden by user/api && not hidden by scrolling/cliprect)
ImU64 RequestOutputMaskByIndex; // Column Index -> IsVisible || AutoFit (== expect user to submit items) ImBitVector RequestOutputMaskByIndex; // Column Index -> IsVisible || AutoFit (== expect user to submit items)
ImGuiTableFlags SettingsLoadedFlags; // Which data were loaded from the .ini file (e.g. when order is not altered we won't save order) ImGuiTableFlags SettingsLoadedFlags; // Which data were loaded from the .ini file (e.g. when order is not altered we won't save order)
int SettingsOffset; // Offset in g.SettingsTables int SettingsOffset; // Offset in g.SettingsTables
int LastFrameActive; int LastFrameActive;

View File

@ -315,7 +315,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
return false; return false;
// Sanity checks // Sanity checks
IM_ASSERT(columns_count > 0 && columns_count <= IMGUI_TABLE_MAX_COLUMNS && "Only 1..64 columns allowed!"); IM_ASSERT(columns_count > 0 && "Only 1..64 columns allowed!");
if (flags & ImGuiTableFlags_ScrollX) if (flags & ImGuiTableFlags_ScrollX)
IM_ASSERT(inner_width >= 0.0f); IM_ASSERT(inner_width >= 0.0f);
@ -358,6 +358,16 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->LastFrameActive = g.FrameCount; table->LastFrameActive = g.FrameCount;
table->OuterWindow = table->InnerWindow = outer_window; table->OuterWindow = table->InnerWindow = outer_window;
table->ColumnsCount = columns_count; table->ColumnsCount = columns_count;
if (table->EnabledMaskByDisplayOrder.BitCount < columns_count ||
table->EnabledMaskByIndex.BitCount < columns_count ||
table->VisibleMaskByIndex.BitCount < columns_count ||
table->RequestOutputMaskByIndex.BitCount < columns_count)
{
table->EnabledMaskByDisplayOrder.Create(columns_count);
table->EnabledMaskByIndex.Create(columns_count);
table->VisibleMaskByIndex.Create(columns_count);
table->RequestOutputMaskByIndex.Create(columns_count);
}
table->IsLayoutLocked = false; table->IsLayoutLocked = false;
table->InnerWidth = inner_width; table->InnerWidth = inner_width;
temp_data->UserOuterSize = outer_size; temp_data->UserOuterSize = outer_size;
@ -721,8 +731,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
const ImGuiTableFlags table_sizing_policy = (table->Flags & ImGuiTableFlags_SizingMask_); const ImGuiTableFlags table_sizing_policy = (table->Flags & ImGuiTableFlags_SizingMask_);
table->IsDefaultDisplayOrder = true; table->IsDefaultDisplayOrder = true;
table->ColumnsEnabledCount = 0; table->ColumnsEnabledCount = 0;
table->EnabledMaskByIndex = 0x00; table->EnabledMaskByIndex.ClearAllBits();
table->EnabledMaskByDisplayOrder = 0x00; table->EnabledMaskByDisplayOrder.ClearAllBits();
table->LeftMostEnabledColumn = -1; table->LeftMostEnabledColumn = -1;
table->MinColumnWidth = ImMax(1.0f, g.Style.FramePadding.x * 1.0f); // g.Style.ColumnsMinSpacing; // FIXME-TABLE table->MinColumnWidth = ImMax(1.0f, g.Style.FramePadding.x * 1.0f); // g.Style.ColumnsMinSpacing; // FIXME-TABLE
@ -787,8 +797,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
else else
table->LeftMostEnabledColumn = (ImGuiTableColumnIdx)column_n; table->LeftMostEnabledColumn = (ImGuiTableColumnIdx)column_n;
column->IndexWithinEnabledSet = table->ColumnsEnabledCount++; column->IndexWithinEnabledSet = table->ColumnsEnabledCount++;
table->EnabledMaskByIndex |= (ImU64)1 << column_n; table->EnabledMaskByIndex |= column_n;
table->EnabledMaskByDisplayOrder |= (ImU64)1 << column->DisplayOrder; table->EnabledMaskByDisplayOrder |= column->DisplayOrder;
prev_visible_column_idx = column_n; prev_visible_column_idx = column_n;
IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder); IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder);
@ -836,7 +846,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
table->LeftMostStretchedColumn = table->RightMostStretchedColumn = -1; table->LeftMostStretchedColumn = table->RightMostStretchedColumn = -1;
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
{ {
if (!(table->EnabledMaskByIndex & ((ImU64)1 << column_n))) if (!(table->EnabledMaskByIndex & column_n))
continue; continue;
ImGuiTableColumn* column = &table->Columns[column_n]; ImGuiTableColumn* column = &table->Columns[column_n];
@ -852,7 +862,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// Latch initial size for fixed columns and update it constantly for auto-resizing column (unless clipped!) // Latch initial size for fixed columns and update it constantly for auto-resizing column (unless clipped!)
if (column->AutoFitQueue != 0x00) if (column->AutoFitQueue != 0x00)
column->WidthRequest = width_auto; column->WidthRequest = width_auto;
else if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !column_is_resizable && (table->RequestOutputMaskByIndex & ((ImU64)1 << column_n))) else if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !column_is_resizable && (table->RequestOutputMaskByIndex & column_n))
column->WidthRequest = width_auto; column->WidthRequest = width_auto;
// FIXME-TABLE: Increase minimum size during init frame to avoid biasing auto-fitting widgets // FIXME-TABLE: Increase minimum size during init frame to avoid biasing auto-fitting widgets
@ -899,7 +909,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
table->ColumnsGivenWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount; table->ColumnsGivenWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount;
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
{ {
if (!(table->EnabledMaskByIndex & ((ImU64)1 << column_n))) if (!(table->EnabledMaskByIndex & column_n))
continue; continue;
ImGuiTableColumn* column = &table->Columns[column_n]; ImGuiTableColumn* column = &table->Columns[column_n];
@ -926,7 +936,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
if (width_remaining_for_stretched_columns >= 1.0f && !(table->Flags & ImGuiTableFlags_PreciseWidths)) 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--) 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 & ((ImU64)1 << order_n))) if (!(table->EnabledMaskByDisplayOrder & order_n))
continue; continue;
ImGuiTableColumn* column = &table->Columns[table->DisplayOrderToIndex[order_n]]; ImGuiTableColumn* column = &table->Columns[table->DisplayOrderToIndex[order_n]];
if (!(column->Flags & ImGuiTableColumnFlags_WidthStretch)) if (!(column->Flags & ImGuiTableColumnFlags_WidthStretch))
@ -949,8 +959,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
float offset_x = ((table->FreezeColumnsCount > 0) ? table->OuterRect.Min.x : work_rect.Min.x) + table->OuterPaddingX - table->CellSpacingX1; float offset_x = ((table->FreezeColumnsCount > 0) ? table->OuterRect.Min.x : work_rect.Min.x) + table->OuterPaddingX - table->CellSpacingX1;
ImRect host_clip_rect = table->InnerClipRect; ImRect host_clip_rect = table->InnerClipRect;
//host_clip_rect.Max.x += table->CellPaddingX + table->CellSpacingX2; //host_clip_rect.Max.x += table->CellPaddingX + table->CellSpacingX2;
table->VisibleMaskByIndex = 0x00; table->VisibleMaskByIndex.ClearAllBits();
table->RequestOutputMaskByIndex = 0x00; table->RequestOutputMaskByIndex.ClearAllBits();
for (int order_n = 0; order_n < table->ColumnsCount; order_n++) for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
{ {
const int column_n = table->DisplayOrderToIndex[order_n]; const int column_n = table->DisplayOrderToIndex[order_n];
@ -967,7 +977,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// Clear status flags // Clear status flags
column->Flags &= ~ImGuiTableColumnFlags_StatusMask_; column->Flags &= ~ImGuiTableColumnFlags_StatusMask_;
if ((table->EnabledMaskByDisplayOrder & ((ImU64)1 << order_n)) == 0) if ((table->EnabledMaskByDisplayOrder & order_n) == 0)
{ {
// Hidden column: clear a few fields and we are done with it for the remainder of the function. // 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. // We set a zero-width clip rect but set Min.y/Max.y properly to not interfere with the clipper.
@ -1020,12 +1030,12 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
column->IsVisibleY = true; // (column->ClipRect.Max.y > column->ClipRect.Min.y); column->IsVisibleY = true; // (column->ClipRect.Max.y > column->ClipRect.Min.y);
const bool is_visible = column->IsVisibleX; //&& column->IsVisibleY; const bool is_visible = column->IsVisibleX; //&& column->IsVisibleY;
if (is_visible) if (is_visible)
table->VisibleMaskByIndex |= ((ImU64)1 << column_n); table->VisibleMaskByIndex |= 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. // 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; column->IsRequestOutput = is_visible || column->AutoFitQueue != 0 || column->CannotSkipItemsQueue != 0;
if (column->IsRequestOutput) if (column->IsRequestOutput)
table->RequestOutputMaskByIndex |= ((ImU64)1 << column_n); table->RequestOutputMaskByIndex |= column_n;
// Mark column as SkipItems (ignoring all items/layout) // Mark column as SkipItems (ignoring all items/layout)
column->IsSkipItems = !column->IsEnabled || table->HostSkipItems; column->IsSkipItems = !column->IsEnabled || table->HostSkipItems;
@ -1153,7 +1163,7 @@ void ImGui::TableUpdateBorders(ImGuiTable* table)
for (int order_n = 0; order_n < table->ColumnsCount; order_n++) for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
{ {
if (!(table->EnabledMaskByDisplayOrder & ((ImU64)1 << order_n))) if (!(table->EnabledMaskByDisplayOrder & order_n))
continue; continue;
const int column_n = table->DisplayOrderToIndex[order_n]; const int column_n = table->DisplayOrderToIndex[order_n];
@ -1289,7 +1299,7 @@ void ImGui::EndTable()
float auto_fit_width_for_stretched = 0.0f; float auto_fit_width_for_stretched = 0.0f;
float auto_fit_width_for_stretched_min = 0.0f; float auto_fit_width_for_stretched_min = 0.0f;
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
if (table->EnabledMaskByIndex & ((ImU64)1 << column_n)) if (table->EnabledMaskByIndex & column_n)
{ {
ImGuiTableColumn* column = &table->Columns[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); float column_width_request = ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !(column->Flags & ImGuiTableColumnFlags_NoResize)) ? column->WidthRequest : TableGetColumnWidthAuto(table, column);
@ -1480,7 +1490,7 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
ImGuiTable* table = g.CurrentTable; ImGuiTable* table = g.CurrentTable;
IM_ASSERT(table != NULL && "Need to call TableSetupColumn() after BeginTable()!"); IM_ASSERT(table != NULL && "Need to call TableSetupColumn() after BeginTable()!");
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!"); IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
IM_ASSERT(columns >= 0 && columns < IMGUI_TABLE_MAX_COLUMNS); IM_ASSERT(columns >= 0);
IM_ASSERT(rows >= 0 && rows < 128); // Arbitrary limit IM_ASSERT(rows >= 0 && rows < 128); // Arbitrary limit
table->FreezeColumnsRequest = (table->Flags & ImGuiTableFlags_ScrollX) ? (ImGuiTableColumnIdx)ImMin(columns, table->ColumnsCount) : 0; table->FreezeColumnsRequest = (table->Flags & ImGuiTableFlags_ScrollX) ? (ImGuiTableColumnIdx)ImMin(columns, table->ColumnsCount) : 0;
@ -1635,7 +1645,7 @@ void ImGui::TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n
return; return;
if (column_n == -1) if (column_n == -1)
column_n = table->CurrentColumn; column_n = table->CurrentColumn;
if ((table->VisibleMaskByIndex & ((ImU64)1 << column_n)) == 0) if ((table->VisibleMaskByIndex & column_n) == 0)
return; return;
if (table->RowCellDataCurrent < 0 || table->RowCellData[table->RowCellDataCurrent].Column != column_n) if (table->RowCellDataCurrent < 0 || table->RowCellData[table->RowCellDataCurrent].Column != column_n)
table->RowCellDataCurrent++; table->RowCellDataCurrent++;
@ -1910,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, // 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. // however they shouldn't skip submitting for columns that may have the tallest contribution to row height.
return (table->RequestOutputMaskByIndex & ((ImU64)1 << column_n)) != 0; return (table->RequestOutputMaskByIndex & column_n) != 0;
} }
// [Public] Append into the next column, wrap and create a new row when already on last column // [Public] Append into the next column, wrap and create a new row when already on last column
@ -1936,7 +1946,7 @@ bool ImGui::TableNextColumn()
// Return whether the column is visible. User may choose to skip submitting items based on this return value, // 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. // however they shouldn't skip submitting for columns that may have the tallest contribution to row height.
int column_n = table->CurrentColumn; int column_n = table->CurrentColumn;
return (table->RequestOutputMaskByIndex & ((ImU64)1 << column_n)) != 0; return (table->RequestOutputMaskByIndex & column_n) != 0;
} }
@ -2349,17 +2359,23 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
{ {
ImRect ClipRect; ImRect ClipRect;
int ChannelsCount; int ChannelsCount;
ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> ChannelsMask; ImBitVector ChannelsMask;
MergeGroup() { ChannelsCount = 0; } MergeGroup(int sz) : ChannelsMask(sz) { ChannelsCount = 0; }
}; };
int merge_group_mask = 0x00; int merge_group_mask = 0x00;
MergeGroup merge_groups[4]; int merge_group_bitlen = IMGUI_TABLE_DRAW_CHANNELS(table->ColumnsCount);
MergeGroup merge_groups[4]{
merge_group_bitlen,
merge_group_bitlen,
merge_group_bitlen,
merge_group_bitlen
};
// 1. Scan channels and take note of those which can be merged // 1. Scan channels and take note of those which can be merged
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
{ {
if ((table->VisibleMaskByIndex & ((ImU64)1 << column_n)) == 0) if ((table->VisibleMaskByIndex & column_n) == 0)
continue; continue;
ImGuiTableColumn* column = &table->Columns[column_n]; ImGuiTableColumn* column = &table->Columns[column_n];
@ -2391,7 +2407,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
} }
const int merge_group_n = (has_freeze_h && column_n < table->FreezeColumnsCount ? 0 : 1) + (has_freeze_v && merge_group_sub_n == 0 ? 0 : 2); const int merge_group_n = (has_freeze_h && column_n < table->FreezeColumnsCount ? 0 : 1) + (has_freeze_v && merge_group_sub_n == 0 ? 0 : 2);
IM_ASSERT(channel_no < IMGUI_TABLE_MAX_DRAW_CHANNELS); IM_ASSERT(channel_no < merge_group_bitlen);
MergeGroup* merge_group = &merge_groups[merge_group_n]; MergeGroup* merge_group = &merge_groups[merge_group_n];
if (merge_group->ChannelsCount == 0) if (merge_group->ChannelsCount == 0)
merge_group->ClipRect = ImRect(+FLT_MAX, +FLT_MAX, -FLT_MAX, -FLT_MAX); merge_group->ClipRect = ImRect(+FLT_MAX, +FLT_MAX, -FLT_MAX, -FLT_MAX);
@ -2431,7 +2447,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
const int LEADING_DRAW_CHANNELS = 2; const int LEADING_DRAW_CHANNELS = 2;
g.DrawChannelsTempMergeBuffer.resize(splitter->_Count - LEADING_DRAW_CHANNELS); // Use shared temporary storage so the allocation gets amortized g.DrawChannelsTempMergeBuffer.resize(splitter->_Count - LEADING_DRAW_CHANNELS); // Use shared temporary storage so the allocation gets amortized
ImDrawChannel* dst_tmp = g.DrawChannelsTempMergeBuffer.Data; ImDrawChannel* dst_tmp = g.DrawChannelsTempMergeBuffer.Data;
ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> remaining_mask; // We need 132-bit of storage ImBitVector remaining_mask(merge_group_bitlen); // We need 132-bit of storage
remaining_mask.SetBitRange(LEADING_DRAW_CHANNELS, splitter->_Count); remaining_mask.SetBitRange(LEADING_DRAW_CHANNELS, splitter->_Count);
remaining_mask.ClearBit(table->Bg2DrawChannelUnfrozen); remaining_mask.ClearBit(table->Bg2DrawChannelUnfrozen);
IM_ASSERT(has_freeze_v == false || table->Bg2DrawChannelUnfrozen != TABLE_DRAW_CHANNEL_BG2_FROZEN); IM_ASSERT(has_freeze_v == false || table->Bg2DrawChannelUnfrozen != TABLE_DRAW_CHANNEL_BG2_FROZEN);
@ -2466,7 +2482,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
GetOverlayDrawList()->AddLine(merge_group->ClipRect.Max, merge_clip_rect.Max, IM_COL32(255, 100, 0, 200)); GetOverlayDrawList()->AddLine(merge_group->ClipRect.Max, merge_clip_rect.Max, IM_COL32(255, 100, 0, 200));
#endif #endif
remaining_count -= merge_group->ChannelsCount; remaining_count -= merge_group->ChannelsCount;
for (int n = 0; n < IM_ARRAYSIZE(remaining_mask.Storage); n++) for (int n = 0; n < remaining_mask.Storage.size(); n++)
remaining_mask.Storage[n] &= ~merge_group->ChannelsMask.Storage[n]; remaining_mask.Storage[n] &= ~merge_group->ChannelsMask.Storage[n];
for (int n = 0; n < splitter->_Count && merge_channels_count != 0; n++) for (int n = 0; n < splitter->_Count && merge_channels_count != 0; n++)
{ {
@ -2523,7 +2539,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
{ {
for (int order_n = 0; order_n < table->ColumnsCount; order_n++) for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
{ {
if (!(table->EnabledMaskByDisplayOrder & ((ImU64)1 << order_n))) if (!(table->EnabledMaskByDisplayOrder & order_n))
continue; continue;
const int column_n = table->DisplayOrderToIndex[order_n]; const int column_n = table->DisplayOrderToIndex[order_n];

View File

@ -696,7 +696,7 @@ void DivEngine::initSongWithDesc(const int* description) {
song.systemFlags[index]=description[i+3]; song.systemFlags[index]=description[i+3];
index++; index++;
chanCount+=getChannelCount(song.system[index]); chanCount+=getChannelCount(song.system[index]);
if (chanCount>=63) break; if (chanCount>=DIV_MAX_CHANS) break;
if (index>=32) break; if (index>=32) break;
} }
song.systemLen=index; song.systemLen=index;
@ -886,9 +886,8 @@ bool DivEngine::addSystem(DivSystem which) {
lastError="max number of systems is 32"; lastError="max number of systems is 32";
return false; return false;
} }
// this was DIV_MAX_CHANS but I am setting it to 63 for now due to an ImGui limitation if (chans+getChannelCount(which)>DIV_MAX_CHANS) {
if (chans+getChannelCount(which)>63) { lastError=fmt::sprintf("max number of total channels is %d",DIV_MAX_CHANS);
lastError="max number of total channels is 63";
return false; return false;
} }
quitDispatch(); quitDispatch();

View File

@ -65,7 +65,7 @@ void DivPlatformSMS::acquire_nuked(short* bufL, short* bufR, size_t start, size_
YMPSG_Clock(&sn_nuked); YMPSG_Clock(&sn_nuked);
YMPSG_Clock(&sn_nuked); YMPSG_Clock(&sn_nuked);
YMPSG_Clock(&sn_nuked); YMPSG_Clock(&sn_nuked);
o=YMPSG_GetOutput(&sn_nuked)*8192.0; o=YMPSG_GetOutput(&sn_nuked);
if (o<-32768) o=-32768; if (o<-32768) o=-32768;
if (o>32767) o=32767; if (o>32767) o=32767;
bufL[h]=o; bufL[h]=o;

View File

@ -186,7 +186,7 @@ bool DivWaveSynth::tick(bool skipSubDiv) {
break; break;
case DIV_WS_PHASE_MOD: case DIV_WS_PHASE_MOD:
for (int i=0; i<=state.speed; i++) { for (int i=0; i<=state.speed; i++) {
int mod=(wave2[pos]*(state.param2-stage)*width)/512; int mod=(wave2[pos]*(state.param2-stage)*width)/(64*(height+1));
output[pos]=wave1[(pos+mod)%width]; output[pos]=wave1[(pos+mod)%width];
if (++pos>=width) { if (++pos>=width) {
pos=0; pos=0;

View File

@ -30,27 +30,48 @@ void FurnaceGUI::drawChannels() {
} }
if (!channelsOpen) return; if (!channelsOpen) return;
if (ImGui::Begin("Channels",&channelsOpen,globalWinFlags)) { if (ImGui::Begin("Channels",&channelsOpen,globalWinFlags)) {
if (ImGui::BeginTable("ChannelList",3)) { if (ImGui::BeginTable("ChannelList",4)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,0.0); ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,0.0);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0); ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,0.0);
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthFixed,48.0f*dpiScale); ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.0);
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthFixed,48.0f*dpiScale);
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableNextColumn();
ImGui::Text("System");
ImGui::TableNextColumn();
ImGui::Text("Visible");
ImGui::TableNextColumn();
ImGui::Text("Name");
for (int i=0; i<e->getTotalChannelCount(); i++) { for (int i=0; i<e->getTotalChannelCount(); i++) {
ImGui::PushID(i); ImGui::PushID(i);
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%s #%d",e->getSystemName(e->sysOfChan[i]), e->dispatchChanOfChan[i]);
ImGui::TableNextColumn();
ImGui::Checkbox("##Visible",&e->curSubSong->chanShow[i]); ImGui::Checkbox("##Visible",&e->curSubSong->chanShow[i]);
ImGui::SameLine(); ImGui::SameLine();
ImGui::BeginDisabled(i==0); if (ImGui::Button(ICON_FA_ARROWS)) {
if (ImGui::Button(ICON_FA_CHEVRON_UP)) {
e->swapChannelsP(i,i-1);
} }
ImGui::EndDisabled(); if (ImGui::BeginDragDropSource()) {
ImGui::SameLine(); chanToMove=i;
ImGui::BeginDisabled(i==(e->getTotalChannelCount()-1)); ImGui::SetDragDropPayload("FUR_CHAN",NULL,0,ImGuiCond_Once);
if (ImGui::Button(ICON_FA_CHEVRON_DOWN)) { ImGui::Text("(release to swap channels)");
e->swapChannelsP(i,i+1); ImGui::EndDragDropSource();
} else if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("(drag to swap channels)");
}
if (ImGui::BeginDragDropTarget()) {
const ImGuiPayload* dragItem=ImGui::AcceptDragDropPayload("FUR_CHAN");
if (dragItem!=NULL) {
if (dragItem->IsDataType("FUR_CHAN")) {
if (chanToMove!=i && chanToMove>=0) {
e->swapChannelsP(chanToMove,i);
}
chanToMove=-1;
}
}
ImGui::EndDragDropTarget();
} }
ImGui::EndDisabled();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
ImGui::InputTextWithHint("##ChanName",e->getChannelName(i),&e->curSubSong->chanName[i]); ImGui::InputTextWithHint("##ChanName",e->getChannelName(i),&e->curSubSong->chanName[i]);

View File

@ -20,6 +20,7 @@
#include "gui.h" #include "gui.h"
#include "debug.h" #include "debug.h"
#include "IconsFontAwesome4.h" #include "IconsFontAwesome4.h"
#include <SDL_timer.h>
#include <fmt/printf.h> #include <fmt/printf.h>
#include <imgui.h> #include <imgui.h>
@ -370,6 +371,13 @@ void FurnaceGUI::drawDebug() {
} }
ImGui::TreePop(); ImGui::TreePop();
} }
if (ImGui::TreeNode("Performance")) {
double perfFreq=SDL_GetPerformanceFrequency()/1000000.0;
ImGui::Text("render: %.0fµs",(double)renderTimeDelta/perfFreq);
ImGui::Text("layout: %.0fµs",(double)layoutTimeDelta/perfFreq);
ImGui::Text("event: %.0fµs",(double)eventTimeDelta/perfFreq);
ImGui::TreePop();
}
if (ImGui::TreeNode("Settings")) { if (ImGui::TreeNode("Settings")) {
if (ImGui::Button("Sync")) syncSettings(); if (ImGui::Button("Sync")) syncSettings();
ImGui::SameLine(); ImGui::SameLine();

View File

@ -2411,6 +2411,7 @@ bool FurnaceGUI::loop() {
drawHalt=0; drawHalt=0;
if (settings.powerSave) SDL_WaitEventTimeout(NULL,500); if (settings.powerSave) SDL_WaitEventTimeout(NULL,500);
} }
eventTimeBegin=SDL_GetPerformanceCounter();
while (SDL_PollEvent(&ev)) { while (SDL_PollEvent(&ev)) {
WAKE_UP; WAKE_UP;
ImGui_ImplSDL2_ProcessEvent(&ev); ImGui_ImplSDL2_ProcessEvent(&ev);
@ -2720,6 +2721,10 @@ bool FurnaceGUI::loop() {
midiQueue.pop(); midiQueue.pop();
midiLock.unlock(); midiLock.unlock();
} }
eventTimeEnd=SDL_GetPerformanceCounter();
layoutTimeBegin=SDL_GetPerformanceCounter();
ImGui_ImplSDLRenderer_NewFrame(); ImGui_ImplSDLRenderer_NewFrame();
ImGui_ImplSDL2_NewFrame(sdlWin); ImGui_ImplSDL2_NewFrame(sdlWin);
@ -3740,6 +3745,8 @@ bool FurnaceGUI::loop() {
ImGui::EndPopup(); ImGui::EndPopup();
} }
layoutTimeEnd=SDL_GetPerformanceCounter();
// backup trigger // backup trigger
if (modified) { if (modified) {
if (backupTimer>0) { if (backupTimer>0) {
@ -3778,10 +3785,16 @@ bool FurnaceGUI::loop() {
uiColors[GUI_COLOR_BACKGROUND].z*255, uiColors[GUI_COLOR_BACKGROUND].z*255,
uiColors[GUI_COLOR_BACKGROUND].w*255); uiColors[GUI_COLOR_BACKGROUND].w*255);
SDL_RenderClear(sdlRend); SDL_RenderClear(sdlRend);
renderTimeBegin=SDL_GetPerformanceCounter();
ImGui::Render(); ImGui::Render();
renderTimeEnd=SDL_GetPerformanceCounter();
ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData());
SDL_RenderPresent(sdlRend); SDL_RenderPresent(sdlRend);
layoutTimeDelta=layoutTimeEnd-layoutTimeBegin;
renderTimeDelta=renderTimeEnd-renderTimeBegin;
eventTimeDelta=eventTimeEnd-eventTimeBegin;
if (--soloTimeout<0) soloTimeout=0; if (--soloTimeout<0) soloTimeout=0;
wheelX=0; wheelX=0;
@ -4283,6 +4296,16 @@ FurnaceGUI::FurnaceGUI():
bindSetPending(false), bindSetPending(false),
nextScroll(-1.0f), nextScroll(-1.0f),
nextAddScroll(0.0f), nextAddScroll(0.0f),
layoutTimeBegin(0),
layoutTimeEnd(0),
layoutTimeDelta(0),
renderTimeBegin(0),
renderTimeEnd(0),
renderTimeDelta(0),
eventTimeBegin(0),
eventTimeEnd(0),
eventTimeDelta(0),
chanToMove(-1),
transposeAmount(0), transposeAmount(0),
randomizeMin(0), randomizeMin(0),
randomizeMax(255), randomizeMax(255),

View File

@ -1189,6 +1189,12 @@ class FurnaceGUI {
float nextScroll, nextAddScroll; float nextScroll, nextAddScroll;
int layoutTimeBegin, layoutTimeEnd, layoutTimeDelta;
int renderTimeBegin, renderTimeEnd, renderTimeDelta;
int eventTimeBegin, eventTimeEnd, eventTimeDelta;
int chanToMove;
ImVec2 patWindowPos, patWindowSize; ImVec2 patWindowPos, patWindowSize;
// pattern view specific // pattern view specific