Merge branch 'master' into docking

# Conflicts:
#	docs/CHANGELOG.txt
#	imgui.cpp
#	imgui.h
#	imgui_draw.cpp
docking^2
ocornut 3 years ago
commit 9948535118

@ -246,7 +246,7 @@ jobs:
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -Wextra -Werror -Wno-zero-as-null-pointer-constant -Wno-double-promotion -Wno-variadic-macros -Wno-empty-body -o example_single_file example_single_file.cpp
g++ -I. -std=c++11 -Wall -Wformat -Wextra -Werror -Wno-zero-as-null-pointer-constant -Wno-double-promotion -Wno-variadic-macros -Wno-empty-body -o example_single_file example_single_file.cpp
- name: Build example_null (freetype)
run: |
@ -262,7 +262,7 @@ jobs:
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with ImWchar32)
run: |
@ -274,7 +274,7 @@ jobs:
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with large ImDrawIdx + pointer ImTextureID)
run: |
@ -287,7 +287,7 @@ jobs:
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_DISABLE_OBSOLETE_FUNCTIONS)
run: |
@ -299,7 +299,7 @@ jobs:
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_DISABLE_OBSOLETE_KEYIO)
run: |
@ -311,7 +311,7 @@ jobs:
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_DISABLE_DEMO_WINDOWS and IMGUI_DISABLE_METRICS_WINDOW)
run: |
@ -324,7 +324,7 @@ jobs:
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_DISABLE_FILE_FUNCTIONS)
run: |
@ -336,7 +336,7 @@ jobs:
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_USE_BGRA_PACKED_COLOR)
run: |
@ -348,7 +348,7 @@ jobs:
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IM_VEC2_CLASS_EXTRA and IM_VEC4_CLASS_EXTRA)
run: |
@ -368,7 +368,7 @@ jobs:
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (without c++ runtime, Clang)
run: |
@ -380,7 +380,7 @@ jobs:
#include "examples/example_null/main.cpp"
EOF
clang++ -I. -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
clang++ -I. -std=c++11 -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
- name: Build example_glfw_opengl2
run: make -C examples/example_glfw_opengl2
@ -397,7 +397,7 @@ jobs:
run: make -C examples/example_sdl_opengl3
- name: Build with IMGUI_IMPL_VULKAN_NO_PROTOTYPES
run: g++ -c -I. -DIMGUI_IMPL_VULKAN_NO_PROTOTYPES=1 backends/imgui_impl_vulkan.cpp
run: g++ -c -I. -std=c++11 -DIMGUI_IMPL_VULKAN_NO_PROTOTYPES=1 backends/imgui_impl_vulkan.cpp
MacOS:
runs-on: macos-latest
@ -420,7 +420,7 @@ jobs:
#include "examples/example_null/main.cpp"
EOF
clang++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
clang++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (without c++ runtime)
run: |
@ -431,7 +431,7 @@ jobs:
#include "examples/example_null/main.cpp"
EOF
clang++ -I. -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
clang++ -I. -std=c++11 -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
- name: Build example_glfw_opengl2
run: make -C examples/example_glfw_opengl2

@ -102,6 +102,22 @@ Other changes:
VERSION 1.88 WIP (In Progress)
-----------------------------------------------------------------------
Breaking changes:
Other Changes:
- Clipper: Fixed a regression in 1.86 when not calling clipper.End() and late destructing the
clipper instance. High-level languages (Lua,Rust etc.) would typically be affected. (#4822)
- IsItemHovered(): added ImGuiHoveredFlags_NoNavOverride to disable the behavior where the
return value is overriden by focus when gamepad/keyboard navigation is active.
- Inputs: Fixed IsMouseClicked() repeat mode rate being half of keyboard repeat rate.
- Stack Tool: Added option to copy item path to clipboard. (#4631)
- Misc: Fixed IsAnyItemHovered() returning false when using navigation.
- Misc: Added constexpr to ImVec2/ImVec4 inline constructors. (#4995) [@Myriachan]
- Misc: binary_to_compressed_c tool: Added -nostatic option. (#5021) [@podsvirov]
- ImVector: Fixed erase() with empty range. (#5009) [@thedmd]
- Drawlist: Fixed PathArcTo() emitting terminating vertices too close to arc vertices. (#4993) [@thedmd]
Docking+Viewports Branch:
- Viewports: Fixed main viewport size not matching ImDrawData::DisplaySize for one frame during resize

@ -17,7 +17,7 @@ LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -f
LIBS += -L/usr/local/lib -L/opt/homebrew/lib
LIBS += -lglfw
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include -I/opt/homebrew/include
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include -I/opt/homebrew/include
CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS)

@ -22,7 +22,7 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s)
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS += -g -Wall -Wformat
LIBS =

@ -23,7 +23,7 @@ OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s)
LINUX_GL_LIBS = -lGL
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS += -g -Wall -Wformat
LIBS =

@ -17,7 +17,7 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glut.cpp $(IMGUI_DIR)/backends/imgui
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s)
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS += -g -Wall -Wformat
LIBS =

@ -17,7 +17,7 @@ SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s)
CXXFLAGS += -I$(IMGUI_DIR)
CXXFLAGS += -std=c++11 -I$(IMGUI_DIR)
CXXFLAGS += -g -Wall -Wformat
LIBS =
@ -52,7 +52,7 @@ endif
ifeq ($(UNAME_S), Darwin) #APPLE
ECHO_MESSAGE = "Mac OS X"
ifeq ($(WITH_EXTRA_WARNINGS), 1)
CXXFLAGS += -Weverything -Wno-reserved-id-macro -Wno-c++98-compat-pedantic -Wno-padded -Wno-c++11-long-long -Wno-poison-system-directories
CXXFLAGS += -Weverything -Wno-reserved-id-macro -Wno-c++98-compat-pedantic -Wno-padded -Wno-poison-system-directories
endif
CFLAGS = $(CXXFLAGS)
endif

@ -17,7 +17,7 @@ LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -f
LIBS += `sdl2-config --libs`
LIBS += -L/usr/local/lib
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include
CXXFLAGS += `sdl2-config --cflags`
CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS)

@ -22,7 +22,7 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl.cpp $(IMGUI_DIR)/backends/imgui_
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s)
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS += -g -Wall -Wformat
LIBS =

@ -23,7 +23,7 @@ OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s)
LINUX_GL_LIBS = -lGL
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS += -g -Wall -Wformat
LIBS =

@ -22,7 +22,7 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl.cpp $(IMGUI_DIR)/backends/imgui_
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s)
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS += -g -Wall -Wformat
LIBS =

@ -82,11 +82,11 @@
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
/*
#define IM_VEC2_CLASS_EXTRA \
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
operator MyVec2() const { return MyVec2(x,y); }
#define IM_VEC4_CLASS_EXTRA \
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
operator MyVec4() const { return MyVec4(x,y,z,w); }
*/

@ -1,4 +1,4 @@
// dear imgui, v1.87
// dear imgui, 1.88 WIP
// (main code and documentation)
// Help:
@ -1216,7 +1216,7 @@ void ImGuiIO::AddInputCharacter(unsigned int c)
return;
ImGuiInputEvent e;
e.Type = ImGuiInputEventType_Char;
e.Type = ImGuiInputEventType_Text;
e.Source = ImGuiInputSource_Keyboard;
e.Text.Char = c;
g.InputEventsQueue.push_back(e);
@ -1286,7 +1286,7 @@ void ImGuiIO::ClearInputKeys()
KeysData[n].DownDurationPrev = -1.0f;
}
KeyCtrl = KeyShift = KeyAlt = KeySuper = false;
KeyMods = KeyModsPrev = ImGuiKeyModFlags_None;
KeyMods = ImGuiKeyModFlags_None;
for (int n = 0; n < IM_ARRAYSIZE(NavInputsDownDuration); n++)
NavInputsDownDuration[n] = NavInputsDownDurationPrev[n] = -1.0f;
}
@ -2614,15 +2614,14 @@ void ImGuiListClipper::Begin(int items_count, float items_height)
void ImGuiListClipper::End()
{
// In theory here we should assert that we are already at the right position, but it seems saner to just seek at the end and not assert/crash the user.
ImGuiContext& g = *GImGui;
if (ImGuiListClipperData* data = (ImGuiListClipperData*)TempData)
{
// In theory here we should assert that we are already at the right position, but it seems saner to just seek at the end and not assert/crash the user.
if (ItemsCount >= 0 && ItemsCount < INT_MAX && DisplayStart >= 0)
ImGuiListClipper_SeekCursorForItem(this, ItemsCount);
ItemsCount = -1;
// Restore temporary buffer and fix back pointers which may be invalidated when nesting
if (ImGuiListClipperData* data = (ImGuiListClipperData*)TempData)
{
IM_ASSERT(data->ListClipper == this);
data->StepNo = data->Ranges.Size;
if (--g.ClipperTempDataStacked > 0)
@ -2632,6 +2631,7 @@ void ImGuiListClipper::End()
}
TempData = NULL;
}
ItemsCount = -1;
}
void ImGuiListClipper::ForceDisplayRangeByIndices(int item_min, int item_max)
@ -2764,8 +2764,8 @@ bool ImGuiListClipper::Step()
// Advance the cursor to the end of the list and then returns 'false' to end the loop.
if (ItemsCount < INT_MAX)
ImGuiListClipper_SeekCursorForItem(this, ItemsCount);
ItemsCount = -1;
End();
return false;
}
@ -3544,7 +3544,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
if (g.NavDisableMouseHover && !g.NavDisableHighlight)
if (g.NavDisableMouseHover && !g.NavDisableHighlight && !(flags & ImGuiHoveredFlags_NoNavOverride))
{
if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
return false;
@ -3607,8 +3607,6 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
return false;
if (!IsMouseHoveringRect(bb.Min, bb.Max))
return false;
if (g.NavDisableMouseHover)
return false;
if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
{
g.HoveredIdDisabled = true;
@ -3644,6 +3642,9 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
IM_DEBUG_BREAK();
}
if (g.NavDisableMouseHover)
return false;
return true;
}
@ -4089,9 +4090,6 @@ static void ImGui::UpdateKeyboardInputs()
ImGuiContext& g = *GImGui;
ImGuiIO& io = g.IO;
// Synchronize io.KeyMods with individual modifiers io.KeyXXX bools
io.KeyMods = GetMergedKeyModFlags();
// Import legacy keys or verify they are not used
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
if (io.BackendUsingLegacyKeyArrays == 0)
@ -4133,6 +4131,9 @@ static void ImGui::UpdateKeyboardInputs()
}
#endif
// Synchronize io.KeyMods with individual modifiers io.KeyXXX bools
io.KeyMods = GetMergedKeyModFlags();
// Clear gamepad data if disabled
if ((io.BackendFlags & ImGuiBackendFlags_HasGamepad) == 0)
for (int i = ImGuiKey_Gamepad_BEGIN; i < ImGuiKey_Gamepad_END; i++)
@ -5107,7 +5108,6 @@ void ImGui::EndFrame()
// Clear Input data for next frame
g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f;
g.IO.InputQueueCharacters.resize(0);
g.IO.KeyModsPrev = g.IO.KeyMods; // doing it here is better than in NewFrame() as we'll tolerate backend writing to KeyMods. If we want to firmly disallow it we should detect it.
memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs));
CallContextHooks(&g, ImGuiContextHookType_EndFramePost);
@ -8254,14 +8254,8 @@ bool ImGui::IsMouseClicked(ImGuiMouseButton button, bool repeat)
const float t = g.IO.MouseDownDuration[button];
if (t == 0.0f)
return true;
if (repeat && t > g.IO.KeyRepeatDelay)
{
// FIXME: 2019/05/03: Our old repeat code was wrong here and led to doubling the repeat rate, which made it an ok rate for repeat on mouse hold.
int amount = CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate * 0.50f);
if (amount > 0)
return true;
}
return CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0;
return false;
}
@ -8483,7 +8477,7 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
}
}
}
else if (e->Type == ImGuiInputEventType_Char)
else if (e->Type == ImGuiInputEventType_Text)
{
// Trickling Rule: Stop processing queued events if keys/mouse have been interacted with
if (trickle_fast_inputs && (key_changed || mouse_button_changed != 0 || mouse_moved || mouse_wheeled))
@ -11452,7 +11446,7 @@ static void ImGui::NavUpdateWindowing()
// - Testing that only Alt is tested prevents Alt+Shift or AltGR from toggling menu layer.
// - AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl). But even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway.
const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
if (nav_keyboard_active && io.KeyMods == ImGuiKeyModFlags_Alt && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) == 0)
if (nav_keyboard_active && IsKeyPressed(ImGuiKey_ModAlt))
{
g.NavWindowingToggleLayer = true;
g.NavInputSource = ImGuiInputSource_Keyboard;
@ -11465,13 +11459,12 @@ static void ImGui::NavUpdateWindowing()
g.NavWindowingToggleLayer = false;
// Apply layer toggle on release
// Important: we don't assume that Alt was previously held in order to handle loss of focus when backend calls io.AddFocusEvent(false)
// Important: as before version <18314 we lacked an explicit IO event for focus gain/loss, we also compare mouse validity to detect old backends clearing mouse pos on focus loss.
if (!(io.KeyMods & ImGuiKeyModFlags_Alt) && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) && g.NavWindowingToggleLayer)
if (IsKeyReleased(ImGuiKey_ModAlt) && g.NavWindowingToggleLayer)
if (g.ActiveId == 0 || g.ActiveIdAllowOverlap)
if (IsMousePosValid(&io.MousePos) == IsMousePosValid(&io.MousePosPrev))
apply_toggle_layer = true;
if (!io.KeyAlt)
if (!IsKeyDown(ImGuiKey_ModAlt))
g.NavWindowingToggleLayer = false;
}
@ -17956,7 +17949,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
int active_id_using_key_input_count = 0;
for (int n = 0; n < ImGuiKey_NamedKey_COUNT; n++)
for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_NamedKey_END; n++)
active_id_using_key_input_count += g.ActiveIdUsingKeyInputMask[n] ? 1 : 0;
Text("ActiveIdUsing: Wheel: %d, NavDirMask: %X, NavInputMask: %X, KeyInputMask: %d key(s)", g.ActiveIdUsingMouseWheel, g.ActiveIdUsingNavDirMask, g.ActiveIdUsingNavInputMask, active_id_using_key_input_count);
Text("HoveredId: 0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Not displaying g.HoveredId as it is update mid-frame
@ -18674,27 +18667,44 @@ void ImGui::DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* dat
ImGuiStackLevelInfo* info = &tool->Results[tool->StackLevel];
IM_ASSERT(info->ID == id && info->QueryFrameCount > 0);
int data_len;
switch (data_type)
{
case ImGuiDataType_S32:
ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%d", (int)(intptr_t)data_id);
break;
case ImGuiDataType_String:
data_len = data_id_end ? (int)((const char*)data_id_end - (const char*)data_id) : (int)strlen((const char*)data_id);
ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "\"%.*s\"", data_len, (const char*)data_id);
ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%.*s", data_id_end ? (int)((const char*)data_id_end - (const char*)data_id) : (int)strlen((const char*)data_id), (const char*)data_id);
break;
case ImGuiDataType_Pointer:
ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "(void*)0x%p", data_id);
break;
case ImGuiDataType_ID:
if (info->Desc[0] == 0) // PushOverrideID() is often used to avoid hashing twice, which would lead to 2 calls to DebugHookIdInfo(). We prioritize the first one.
if (info->Desc[0] != 0) // PushOverrideID() is often used to avoid hashing twice, which would lead to 2 calls to DebugHookIdInfo(). We prioritize the first one.
return;
ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "0x%08X [override]", id);
break;
default:
IM_ASSERT(0);
}
info->QuerySuccess = true;
info->DataType = data_type;
}
static int StackToolFormatLevelInfo(ImGuiStackTool* tool, int n, bool format_for_ui, char* buf, size_t buf_size)
{
ImGuiStackLevelInfo* info = &tool->Results[n];
ImGuiWindow* window = (info->Desc[0] == 0 && n == 0) ? ImGui::FindWindowByID(info->ID) : NULL;
if (window) // Source: window name (because the root ID don't call GetID() and so doesn't get hooked)
return ImFormatString(buf, buf_size, format_for_ui ? "\"%s\" [window]" : "%s", window->Name);
if (info->QuerySuccess) // Source: GetID() hooks (prioritize over ItemInfo() because we frequently use patterns like: PushID(str), Button("") where they both have same id)
return ImFormatString(buf, buf_size, (format_for_ui && info->DataType == ImGuiDataType_String) ? "\"%s\"" : "%s", info->Desc);
if (tool->StackLevel < tool->Results.Size) // Only start using fallback below when all queries are done, so during queries we don't flickering ??? markers.
return (*buf = 0);
#ifdef IMGUI_ENABLE_TEST_ENGINE
if (const char* label = ImGuiTestEngine_FindItemDebugLabel(GImGui, info->ID)) // Source: ImGuiTestEngine's ItemInfo()
return ImFormatString(buf, buf_size, format_for_ui ? "??? \"%s\"" : "%s", label);
#endif
return ImFormatString(buf, buf_size, "???");
}
// Stack Tool: Display UI
@ -18710,6 +18720,7 @@ void ImGui::ShowStackToolWindow(bool* p_open)
}
// Display hovered/active status
ImGuiStackTool* tool = &g.DebugStackTool;
const ImGuiID hovered_id = g.HoveredIdPreviousFrame;
const ImGuiID active_id = g.ActiveId;
#ifdef IMGUI_ENABLE_TEST_ENGINE
@ -18720,8 +18731,33 @@ void ImGui::ShowStackToolWindow(bool* p_open)
SameLine();
MetricsHelpMarker("Hover an item with the mouse to display elements of the ID Stack leading to the item's final ID.\nEach level of the stack correspond to a PushID() call.\nAll levels of the stack are hashed together to make the final ID of a widget (ID displayed at the bottom level of the stack).\nRead FAQ entry about the ID stack for details.");
// CTRL+C to copy path
const float time_since_copy = (float)g.Time - tool->CopyToClipboardLastTime;
Checkbox("Ctrl+C: copy path to clipboard", &tool->CopyToClipboardOnCtrlC);
SameLine();
TextColored((time_since_copy >= 0.0f && time_since_copy < 0.75f && ImFmod(time_since_copy, 0.25f) < 0.25f * 0.5f) ? ImVec4(1.f, 1.f, 0.3f, 1.f) : ImVec4(), "*COPIED*");
if (tool->CopyToClipboardOnCtrlC && IsKeyDown(ImGuiKey_ModCtrl) && IsKeyPressed(ImGuiKey_C))
{
tool->CopyToClipboardLastTime = (float)g.Time;
char* p = g.TempBuffer;
char* p_end = p + IM_ARRAYSIZE(g.TempBuffer);
for (int stack_n = 0; stack_n < tool->Results.Size && p + 3 < p_end; stack_n++)
{
*p++ = '/';
char level_desc[256];
StackToolFormatLevelInfo(tool, stack_n, false, level_desc, IM_ARRAYSIZE(level_desc));
for (int n = 0; level_desc[n] && p + 2 < p_end; n++)
{
if (level_desc[n] == '/')
*p++ = '\\';
*p++ = level_desc[n];
}
}
*p = '\0';
SetClipboardText(g.TempBuffer);
}
// Display decorated stack
ImGuiStackTool* tool = &g.DebugStackTool;
tool->LastActiveFrame = g.FrameCount;
if (tool->Results.Size > 0 && BeginTable("##table", 3, ImGuiTableFlags_Borders))
{
@ -18735,23 +18771,9 @@ void ImGui::ShowStackToolWindow(bool* p_open)
ImGuiStackLevelInfo* info = &tool->Results[n];
TableNextColumn();
Text("0x%08X", (n > 0) ? tool->Results[n - 1].ID : 0);
TableNextColumn();
ImGuiWindow* window = (info->Desc[0] == 0 && n == 0) ? FindWindowByID(info->ID) : NULL;
if (window) // Source: window name (because the root ID don't call GetID() and so doesn't get hooked)
Text("\"%s\" [window]", window->Name);
else if (info->QuerySuccess) // Source: GetID() hooks (prioritize over ItemInfo() because we frequently use patterns like: PushID(str), Button("") where they both have same id)
TextUnformatted(info->Desc);
else if (tool->StackLevel >= tool->Results.Size) // Only start using fallback below when all queries are done, so during queries we don't flickering ??? markers.
{
#ifdef IMGUI_ENABLE_TEST_ENGINE
if (const char* label = ImGuiTestEngine_FindItemDebugLabel(&g, info->ID)) // Source: ImGuiTestEngine's ItemInfo()
Text("??? \"%s\"", label);
else
#endif
TextUnformatted("???");
}
StackToolFormatLevelInfo(tool, n, true, g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer));
TextUnformatted(g.TempBuffer);
TableNextColumn();
Text("0x%08X", info->ID);
if (n == tool->Results.Size - 1)

@ -1,4 +1,4 @@
// dear imgui, v1.87
// dear imgui, v1.88 WIP
// (headers)
// Help:
@ -64,8 +64,8 @@ Index of this file:
// Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.87"
#define IMGUI_VERSION_NUM 18701
#define IMGUI_VERSION "1.88 WIP"
#define IMGUI_VERSION_NUM 18707
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
@ -255,8 +255,8 @@ IM_MSVC_RUNTIME_CHECKS_OFF
struct ImVec2
{
float x, y;
ImVec2() { x = y = 0.0f; }
ImVec2(float _x, float _y) { x = _x; y = _y; }
constexpr ImVec2() : x(0.0f), y(0.0f) { }
constexpr ImVec2(float _x, float _y) : x(_x), y(_y) { }
float operator[] (size_t idx) const { IM_ASSERT(idx <= 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine.
float& operator[] (size_t idx) { IM_ASSERT(idx <= 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine.
#ifdef IM_VEC2_CLASS_EXTRA
@ -268,8 +268,8 @@ struct ImVec2
struct ImVec4
{
float x, y, z, w;
ImVec4() { x = y = z = w = 0.0f; }
ImVec4(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; }
constexpr ImVec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) { }
constexpr ImVec4(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) { }
#ifdef IM_VEC4_CLASS_EXTRA
IM_VEC4_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4.
#endif
@ -1327,6 +1327,7 @@ enum ImGuiHoveredFlags_
ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 7, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns.
ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 8, // IsItemHovered() only: Return true even if the position is obstructed or overlapped by another window
ImGuiHoveredFlags_AllowWhenDisabled = 1 << 9, // IsItemHovered() only: Return true even if the item is disabled
ImGuiHoveredFlags_NoNavOverride = 1 << 10, // Disable using gamepad/keyboard navigation state when active, always query mouse.
ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped,
ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows
};
@ -1893,7 +1894,7 @@ struct ImVector
inline void pop_back() { IM_ASSERT(Size > 0); Size--; }
inline void push_front(const T& v) { if (Size == 0) push_back(v); else insert(Data, v); }
inline T* erase(const T* it) { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(T)); Size--; return Data + off; }
inline T* erase(const T* it, const T* it_last){ IM_ASSERT(it >= Data && it < Data + Size && it_last > it && it_last <= Data + Size); const ptrdiff_t count = it_last - it; const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + count, ((size_t)Size - (size_t)off - (size_t)count) * sizeof(T)); Size -= (int)count; return Data + off; }
inline T* erase(const T* it, const T* it_last){ IM_ASSERT(it >= Data && it < Data + Size && it_last >= it && it_last <= Data + Size); const ptrdiff_t count = it_last - it; const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + count, ((size_t)Size - (size_t)off - (size_t)count) * sizeof(T)); Size -= (int)count; return Data + off; }
inline T* erase_unsorted(const T* it) { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; if (it < Data + Size - 1) memcpy(Data + off, Data + Size - 1, sizeof(T)); Size--; return Data + off; }
inline T* insert(const T* it, const T& v) { IM_ASSERT(it >= Data && it <= Data + Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(_grow_capacity(Size + 1)); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(T)); memcpy(&Data[off], &v, sizeof(v)); Size++; return Data + off; }
inline bool contains(const T& v) const { const T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data++ == v) return true; return false; }
@ -2121,7 +2122,6 @@ struct ImGuiIO
// Other state maintained from data above + IO function calls
ImGuiKeyModFlags KeyMods; // Key mods flags (same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags), updated by NewFrame()
ImGuiKeyModFlags KeyModsPrev; // Key mods flags (from previous frame)
ImGuiKeyData KeysData[ImGuiKey_KeysData_SIZE]; // Key state for all known keys. Use IsKeyXXX() functions to access this.
bool WantCaptureMouseUnlessPopupClose; // Alternative to WantCaptureMouse: (WantCaptureMouse == true && WantCaptureMouseUnlessPopupClose == false) when a click over void is expected to close a popup.
ImVec2 MousePosPrev; // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid)

@ -1,4 +1,4 @@
// dear imgui, v1.87
// dear imgui, v1.88 WIP
// (demo code)
// Help:

@ -1,4 +1,4 @@
// dear imgui, v1.87
// dear imgui, v1.88 WIP
// (drawing and font code)
/*
@ -1214,8 +1214,8 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
const float a_max_segment_angle = a_max_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
const bool a_emit_start = (a_min_segment_angle - a_min) != 0.0f;
const bool a_emit_end = (a_max - a_max_segment_angle) != 0.0f;
const bool a_emit_start = ImAbs(a_min_segment_angle - a_min) >= 1e-5f;
const bool a_emit_end = ImAbs(a_max - a_max_segment_angle) >= 1e-5f;
_Path.reserve(_Path.Size + (a_mid_samples + 1 + (a_emit_start ? 1 : 0) + (a_emit_end ? 1 : 0)));
if (a_emit_start)

@ -1,4 +1,4 @@
// dear imgui, v1.87
// dear imgui, v1.88 WIP
// (internal structures/api)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
@ -481,17 +481,17 @@ IM_MSVC_RUNTIME_CHECKS_OFF
struct ImVec1
{
float x;
ImVec1() { x = 0.0f; }
ImVec1(float _x) { x = _x; }
constexpr ImVec1() : x(0.0f) { }
constexpr ImVec1(float _x) : x(_x) { }
};
// Helper: ImVec2ih (2D vector, half-size integer, for long-term packed storage)
struct ImVec2ih
{
short x, y;
ImVec2ih() { x = y = 0; }
ImVec2ih(short _x, short _y) { x = _x; y = _y; }
explicit ImVec2ih(const ImVec2& rhs) { x = (short)rhs.x; y = (short)rhs.y; }
constexpr ImVec2ih() : x(0), y(0) {}
constexpr ImVec2ih(short _x, short _y) : x(_x), y(_y) {}
constexpr explicit ImVec2ih(const ImVec2& rhs) : x((short)rhs.x), y((short)rhs.y) {}
};
// Helper: ImRect (2D axis aligned bounding-box)
@ -501,10 +501,10 @@ struct IMGUI_API ImRect
ImVec2 Min; // Upper-left
ImVec2 Max; // Lower-right
ImRect() : Min(0.0f, 0.0f), Max(0.0f, 0.0f) {}
ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {}
ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {}
ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {}
constexpr ImRect() : Min(0.0f, 0.0f), Max(0.0f, 0.0f) {}
constexpr ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {}
constexpr ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {}
constexpr ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {}
ImVec2 GetCenter() const { return ImVec2((Min.x + Max.x) * 0.5f, (Min.y + Max.y) * 0.5f); }
ImVec2 GetSize() const { return ImVec2(Max.x - Min.x, Max.y - Min.y); }
@ -559,11 +559,11 @@ struct ImBitArray
ImBitArray() { ClearAllBits(); }
void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); }
void SetAllBits() { memset(Storage, 255, sizeof(Storage)); }
bool TestBit(int n) const { IM_ASSERT(n + OFFSET < BITCOUNT); return ImBitArrayTestBit(Storage, n + OFFSET); }
void SetBit(int n) { IM_ASSERT(n + OFFSET < BITCOUNT); ImBitArraySetBit(Storage, n + OFFSET); }
void ClearBit(int n) { IM_ASSERT(n + OFFSET < BITCOUNT); ImBitArrayClearBit(Storage, n + OFFSET); }
void SetBitRange(int n, int n2) { ImBitArraySetBitRange(Storage, n + OFFSET, n2 + OFFSET); } // Works on range [n..n2)
bool operator[](int n) const { IM_ASSERT(n + OFFSET < BITCOUNT); return ImBitArrayTestBit(Storage, n + OFFSET); }
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 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); }
};
// Helper: ImBitVector
@ -1192,7 +1192,7 @@ enum ImGuiInputEventType
ImGuiInputEventType_MouseButton,
ImGuiInputEventType_MouseViewport,
ImGuiInputEventType_Key,
ImGuiInputEventType_Char,
ImGuiInputEventType_Text,
ImGuiInputEventType_Focus,
ImGuiInputEventType_COUNT
};
@ -1686,7 +1686,8 @@ struct ImGuiStackLevelInfo
ImGuiID ID;
ImS8 QueryFrameCount; // >= 1: Query in progress
bool QuerySuccess; // Obtained result from DebugHookIdInfo()
char Desc[58]; // Arbitrarily sized buffer to hold a result (FIXME: could replace Results[] with a chunk stream?)
ImGuiDataType DataType : 8;
char Desc[57]; // Arbitrarily sized buffer to hold a result (FIXME: could replace Results[] with a chunk stream?) FIXME: Now that we added CTRL+C this should be fixed.
ImGuiStackLevelInfo() { memset(this, 0, sizeof(*this)); }
};
@ -1698,8 +1699,10 @@ struct ImGuiStackTool
int StackLevel; // -1: query stack and resize Results, >= 0: individual stack level
ImGuiID QueryId; // ID to query details for
ImVector<ImGuiStackLevelInfo> Results;
bool CopyToClipboardOnCtrlC;
float CopyToClipboardLastTime;
ImGuiStackTool() { memset(this, 0, sizeof(*this)); }
ImGuiStackTool() { memset(this, 0, sizeof(*this)); CopyToClipboardLastTime = -FLT_MAX; }
};
//-----------------------------------------------------------------------------

@ -1,4 +1,4 @@
// dear imgui, v1.87
// dear imgui, v1.88 WIP
// (tables and columns code)
/*

@ -1,4 +1,4 @@
// dear imgui, v1.87
// dear imgui, v1.88 WIP
// (widgets code)
/*
@ -82,6 +82,7 @@ Index of this file:
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
#pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
#endif
//-------------------------------------------------------------------------
@ -6937,7 +6938,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
if (!enabled)
EndDisabled();
const bool hovered = (g.HoveredId == id) && enabled;
const bool hovered = (g.HoveredId == id) && enabled && !g.NavDisableMouseHover;
if (menuset_is_open)
g.NavWindow = backed_nav_window;

@ -15,7 +15,7 @@
// You can also find a precompiled Windows binary in the binary/demo package available from https://github.com/ocornut/imgui
// Usage:
// binary_to_compressed_c.exe [-base85] [-nocompress] <inputfile> <symbolname>
// binary_to_compressed_c.exe [-base85] [-nocompress] [-nostatic] <inputfile> <symbolname>
// Usage example:
// # binary_to_compressed_c.exe myfont.ttf MyFont > myfont.cpp
// # binary_to_compressed_c.exe -base85 myfont.ttf MyFont > myfont.cpp
@ -31,23 +31,25 @@ typedef unsigned int stb_uint;
typedef unsigned char stb_uchar;
stb_uint stb_compress(stb_uchar* out, stb_uchar* in, stb_uint len);
static bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression);
static bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression, bool use_static);
int main(int argc, char** argv)
{
if (argc < 3)
{
printf("Syntax: %s [-base85] [-nocompress] <inputfile> <symbolname>\n", argv[0]);
printf("Syntax: %s [-base85] [-nocompress] [-nostatic] <inputfile> <symbolname>\n", argv[0]);
return 0;
}
int argn = 1;
bool use_base85_encoding = false;
bool use_compression = true;
if (argv[argn][0] == '-')
bool use_static = true;
while (argn < (argc - 2) && argv[argn][0] == '-')
{
if (strcmp(argv[argn], "-base85") == 0) { use_base85_encoding = true; argn++; }
else if (strcmp(argv[argn], "-nocompress") == 0) { use_compression = false; argn++; }
else if (strcmp(argv[argn], "-nostatic") == 0) { use_static = false; argn++; }
else
{
fprintf(stderr, "Unknown argument: '%s'\n", argv[argn]);
@ -55,7 +57,7 @@ int main(int argc, char** argv)
}
}
bool ret = binary_to_compressed_c(argv[argn], argv[argn + 1], use_base85_encoding, use_compression);
bool ret = binary_to_compressed_c(argv[argn], argv[argn + 1], use_base85_encoding, use_compression, use_static);
if (!ret)
fprintf(stderr, "Error opening or reading file: '%s'\n", argv[argn]);
return ret ? 0 : 1;
@ -67,7 +69,7 @@ char Encode85Byte(unsigned int x)
return (x >= '\\') ? x + 1 : x;
}
bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression)
bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression, bool use_static)
{
// Read file
FILE* f = fopen(filename, "rb");
@ -90,10 +92,11 @@ bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_b
FILE* out = stdout;
fprintf(out, "// File: '%s' (%d bytes)\n", filename, (int)data_sz);
fprintf(out, "// Exported using binary_to_compressed_c.cpp\n");
const char* static_str = use_static ? "static " : "";
const char* compressed_str = use_compression ? "compressed_" : "";
if (use_base85_encoding)
{
fprintf(out, "static const char %s_%sdata_base85[%d+1] =\n \"", symbol, compressed_str, (int)((compressed_sz + 3) / 4)*5);
fprintf(out, "%sconst char %s_%sdata_base85[%d+1] =\n \"", static_str, symbol, compressed_str, (int)((compressed_sz + 3) / 4)*5);
char prev_c = 0;
for (int src_i = 0; src_i < compressed_sz; src_i += 4)
{
@ -112,8 +115,8 @@ bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_b
}
else
{
fprintf(out, "static const unsigned int %s_%ssize = %d;\n", symbol, compressed_str, (int)compressed_sz);
fprintf(out, "static const unsigned int %s_%sdata[%d/4] =\n{", symbol, compressed_str, (int)((compressed_sz + 3) / 4)*4);
fprintf(out, "%sconst unsigned int %s_%ssize = %d;\n", static_str, symbol, compressed_str, (int)compressed_sz);
fprintf(out, "%sconst unsigned int %s_%sdata[%d/4] =\n{", static_str, symbol, compressed_str, (int)((compressed_sz + 3) / 4)*4);
int column = 0;
for (int i = 0; i < compressed_sz; i += 4)
{

Loading…
Cancel
Save