// File: Ciaxur[P]yagb-emu/include/imgui/imgui_widgets.cpp
// Function: ImGui::ScrollbarEx(ImRect const&, unsigned int, ImGuiAxis, float*, float, float, int)
bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, float* p_scroll_v, float size_avail_v, float size_contents_v, ImDrawCornerFlags rounding_corners)
{
    ImGuiContext& g = *GImGui;
    ImGuiWindow* window = g.CurrentWindow;
    if (window->SkipItems)
        return false;

    const float bb_frame_width = bb_frame.GetWidth();
    const float bb_frame_height = bb_frame.GetHeight();
    if (bb_frame_width <= 0.0f || bb_frame_height <= 0.0f)
        return false;

    // When we are too small, start hiding and disabling the grab (this reduce visual noise on very small window and facilitate using the window resize grab)
    float alpha = 1.0f;
    if ((axis == ImGuiAxis_Y) && bb_frame_height < g.FontSize + g.Style.FramePadding.y * 2.0f)
        alpha = ImSaturate((bb_frame_height - g.FontSize) / (g.Style.FramePadding.y * 2.0f));
    if (alpha <= 0.0f)
        return false;

    const ImGuiStyle& style = g.Style;
    const bool allow_interaction = (alpha >= 1.0f);

    ImRect bb = bb_frame;
    bb.Expand(ImVec2(-ImClamp(IM_FLOOR((bb_frame_width - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp(IM_FLOOR((bb_frame_height - 2.0f) * 0.5f), 0.0f, 3.0f)));

    // V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar)
    const float scrollbar_size_v = (axis == ImGuiAxis_X) ? bb.GetWidth() : bb.GetHeight();

    // Calculate the height of our grabbable box. It generally represent the amount visible (vs the total scrollable amount)
    // But we maintain a minimum size in pixel to allow for the user to still aim inside.
    IM_ASSERT(ImMax(size_contents_v, size_avail_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers.
    const float win_size_v = ImMax(ImMax(size_contents_v, size_avail_v), 1.0f);
    const float grab_h_pixels = ImClamp(scrollbar_size_v * (size_avail_v / win_size_v), style.GrabMinSize, scrollbar_size_v);
    const float grab_h_norm = grab_h_pixels / scrollbar_size_v;

    // Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar().
    bool held = false;
    bool hovered = false;
    ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_NoNavFocus);

    float scroll_max = ImMax(1.0f, size_contents_v - size_avail_v);
    float scroll_ratio = ImSaturate(*p_scroll_v / scroll_max);
    float grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; // Grab position in normalized space
    if (held && allow_interaction && grab_h_norm < 1.0f)
    {
        float scrollbar_pos_v = bb.Min[axis];
        float mouse_pos_v = g.IO.MousePos[axis];

        // Click position in scrollbar normalized space (0.0f->1.0f)
        const float clicked_v_norm = ImSaturate((mouse_pos_v - scrollbar_pos_v) / scrollbar_size_v);
        SetHoveredID(id);

        bool seek_absolute = false;
        if (g.ActiveIdIsJustActivated)
        {
            // On initial click calculate the distance between mouse and the center of the grab
            seek_absolute = (clicked_v_norm < grab_v_norm || clicked_v_norm > grab_v_norm + grab_h_norm);
            if (seek_absolute)
                g.ScrollbarClickDeltaToGrabCenter = 0.0f;
            else
                g.ScrollbarClickDeltaToGrabCenter = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f;
        }

        // Apply scroll (p_scroll_v will generally point on one member of window->Scroll)
        // It is ok to modify Scroll here because we are being called in Begin() after the calculation of ContentSize and before setting up our starting position
        const float scroll_v_norm = ImSaturate((clicked_v_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm * 0.5f) / (1.0f - grab_h_norm));
        *p_scroll_v = IM_ROUND(scroll_v_norm * scroll_max);//(win_size_contents_v - win_size_v));

        // Update values for rendering
        scroll_ratio = ImSaturate(*p_scroll_v / scroll_max);
        grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v;

        // Update distance to grab now that we have seeked and saturated
        if (seek_absolute)
            g.ScrollbarClickDeltaToGrabCenter = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f;
    }

    // Render
    const ImU32 bg_col = GetColorU32(ImGuiCol_ScrollbarBg);
    const ImU32 grab_col = GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab, alpha);
    window->DrawList->AddRectFilled(bb_frame.Min, bb_frame.Max, bg_col, window->WindowRounding, rounding_corners);
    ImRect grab_rect;
    if (axis == ImGuiAxis_X)
        grab_rect = ImRect(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm), bb.Min.y, ImLerp(bb.Min.x, bb.Max.x, grab_v_norm) + grab_h_pixels, bb.Max.y);
    else
        grab_rect = ImRect(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm), bb.Max.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm) + grab_h_pixels);
    window->DrawList->AddRectFilled(grab_rect.Min, grab_rect.Max, grab_col, style.ScrollbarRounding);

    return held;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x110, %rsp            # imm = 0x110
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movss %xmm0, -0x24(%rbp)
movss %xmm1, -0x28(%rbp)
movl %r8d, -0x2c(%rbp)
leaq 0xd7732(%rip), %rax     # 0x212f40
movq (%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq 0x1ae0(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
testb $0x1, 0x93(%rax)
je 0x13b83a
movb $0x0, -0x1(%rbp)
jmp 0x13bfac
movq -0x10(%rbp), %rdi
callq 0xeb840
movss %xmm0, -0x44(%rbp)
movq -0x10(%rbp), %rdi
callq 0xeb860
movss %xmm0, -0x48(%rbp)
xorps %xmm0, %xmm0
ucomiss -0x44(%rbp), %xmm0
jae 0x13b868
xorps %xmm0, %xmm0
ucomiss -0x48(%rbp), %xmm0
jb 0x13b871
movb $0x0, -0x1(%rbp)
jmp 0x13bfac
movss 0x353c3(%rip), %xmm0    # 0x170c3c
movss %xmm0, -0x4c(%rbp)
cmpl $0x1, -0x18(%rbp)
jne 0x13b8e1
movss -0x48(%rbp), %xmm1
movq -0x38(%rbp), %rax
movss 0x1980(%rax), %xmm2
movq -0x38(%rbp), %rax
movss 0x159c(%rax), %xmm0
addss %xmm0, %xmm0
addss %xmm2, %xmm0
ucomiss %xmm1, %xmm0
jbe 0x13b8e1
movss -0x48(%rbp), %xmm0
movq -0x38(%rbp), %rax
subss 0x1980(%rax), %xmm0
movq -0x38(%rbp), %rax
movss 0x36701(%rip), %xmm1    # 0x171fcc
mulss 0x159c(%rax), %xmm1
divss %xmm1, %xmm0
callq 0x13bfc0
movss %xmm0, -0x4c(%rbp)
xorps %xmm0, %xmm0
ucomiss -0x4c(%rbp), %xmm0
jb 0x13b8f3
movb $0x0, -0x1(%rbp)
jmp 0x13bfac
movq -0x38(%rbp), %rax
addq $0x1560, %rax           # imm = 0x1560
movq %rax, -0x58(%rbp)
movss -0x4c(%rbp), %xmm0
movss 0x3532e(%rip), %xmm1    # 0x170c3c
ucomiss %xmm1, %xmm0
setae %al
andb $0x1, %al
movb %al, -0x59(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x6c(%rbp)
movq 0x8(%rax), %rax
movq %rax, -0x64(%rbp)
movss -0x44(%rbp), %xmm0
movss 0x36693(%rip), %xmm1    # 0x171fcc
subss %xmm1, %xmm0
movss 0x36693(%rip), %xmm1    # 0x171fd8
mulss %xmm1, %xmm0
cvttss2si %xmm0, %eax
cvtsi2ss %eax, %xmm0
xorps %xmm1, %xmm1
movss 0x36664(%rip), %xmm2    # 0x171fc0
callq 0x13c020
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
movss %xmm0, -0xe4(%rbp)
movss -0x48(%rbp), %xmm0
movss 0x36649(%rip), %xmm1    # 0x171fcc
subss %xmm1, %xmm0
movss 0x36649(%rip), %xmm1    # 0x171fd8
mulss %xmm1, %xmm0
cvttss2si %xmm0, %eax
cvtsi2ss %eax, %xmm0
xorps %xmm1, %xmm1
movss 0x3661a(%rip), %xmm2    # 0x171fc0
callq 0x13c020
movaps %xmm0, %xmm1
movss -0xe4(%rbp), %xmm0
movd %xmm1, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm1
leaq -0x74(%rbp), %rdi
callq 0xbf4c0
leaq -0x6c(%rbp), %rdi
leaq -0x74(%rbp), %rsi
callq 0xe89d0
cmpl $0x0, -0x18(%rbp)
jne 0x13b9f2
leaq -0x6c(%rbp), %rdi
callq 0xeb840
movss %xmm0, -0xe8(%rbp)
jmp 0x13ba03
leaq -0x6c(%rbp), %rdi
callq 0xeb860
movss %xmm0, -0xe8(%rbp)
movss -0xe8(%rbp), %xmm0
movss %xmm0, -0x78(%rbp)
movss -0x28(%rbp), %xmm0
movss -0x24(%rbp), %xmm1
callq 0x139050
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jbe 0x13ba29
jmp 0x13ba48
leaq 0x52b7c(%rip), %rdi     # 0x18e5ac
leaq 0x529a9(%rip), %rsi     # 0x18e3e0
movl $0x399, %edx            # imm = 0x399
leaq 0x52b95(%rip), %rcx     # 0x18e5d8
callq 0xd180
movss -0x28(%rbp), %xmm0
movss -0x24(%rbp), %xmm1
callq 0x139050
movss 0x351dd(%rip), %xmm1    # 0x170c3c
callq 0x139050
movss %xmm0, -0x7c(%rbp)
movss -0x78(%rbp), %xmm0
movss -0x24(%rbp), %xmm1
divss -0x7c(%rbp), %xmm1
mulss %xmm1, %xmm0
movq -0x58(%rbp), %rax
movss 0x78(%rax), %xmm1
movss -0x78(%rbp), %xmm2
callq 0x13c020
movss %xmm0, -0x80(%rbp)
movss -0x80(%rbp), %xmm0
divss -0x78(%rbp), %xmm0
movss %xmm0, -0x84(%rbp)
movb $0x0, -0x85(%rbp)
movb $0x0, -0x86(%rbp)
movl -0x14(%rbp), %esi
leaq -0x6c(%rbp), %rdi
leaq -0x86(%rbp), %rdx
leaq -0x85(%rbp), %rcx
movl $0x40000, %r8d          # imm = 0x40000
callq 0x139df0
movss -0x28(%rbp), %xmm1
subss -0x24(%rbp), %xmm1
movss 0x35156(%rip), %xmm0    # 0x170c3c
callq 0x139050
movss %xmm0, -0x8c(%rbp)
movq -0x20(%rbp), %rax
movss (%rax), %xmm0
divss -0x8c(%rbp), %xmm0
callq 0x13bfc0
movss %xmm0, -0x90(%rbp)
movss -0x90(%rbp), %xmm0
movss -0x78(%rbp), %xmm1
subss -0x80(%rbp), %xmm1
mulss %xmm1, %xmm0
divss -0x78(%rbp), %xmm0
movss %xmm0, -0x94(%rbp)
testb $0x1, -0x85(%rbp)
je 0x13bda0
testb $0x1, -0x59(%rbp)
je 0x13bda0
movss 0x350ea(%rip), %xmm0    # 0x170c3c
ucomiss -0x84(%rbp), %xmm0
jbe 0x13bda0
leaq -0x6c(%rbp), %rdi
movslq -0x18(%rbp), %rsi
callq 0x15bb20
movss (%rax), %xmm0
movss %xmm0, -0x98(%rbp)
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
addq $0x120, %rdi            # imm = 0x120
movslq -0x18(%rbp), %rsi
callq 0x15bb20
movss (%rax), %xmm0
movss %xmm0, -0x9c(%rbp)
movss -0x9c(%rbp), %xmm0
subss -0x98(%rbp), %xmm0
divss -0x78(%rbp), %xmm0
callq 0x13bfc0
movss %xmm0, -0xa0(%rbp)
movl -0x14(%rbp), %edi
callq 0xca060
movb $0x0, -0xa1(%rbp)
movq -0x38(%rbp), %rax
testb $0x1, 0x1b3c(%rax)
je 0x13bc8a
movss -0xa0(%rbp), %xmm1
movss -0x94(%rbp), %xmm0
movb $0x1, %al
ucomiss %xmm1, %xmm0
movb %al, -0xe9(%rbp)
ja 0x13bc1f
movss -0xa0(%rbp), %xmm0
movss -0x94(%rbp), %xmm1
addss -0x84(%rbp), %xmm1
ucomiss %xmm1, %xmm0
seta %al
movb %al, -0xe9(%rbp)
movb -0xe9(%rbp), %al
andb $0x1, %al
movb %al, -0xa1(%rbp)
testb $0x1, -0xa1(%rbp)
je 0x13bc47
movq -0x38(%rbp), %rax
xorps %xmm0, %xmm0
movss %xmm0, 0x30a4(%rax)
jmp 0x13bc88
movss -0xa0(%rbp), %xmm1
subss -0x94(%rbp), %xmm1
movss -0x84(%rbp), %xmm0
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
movss 0x36364(%rip), %xmm2    # 0x171fd8
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movq -0x38(%rbp), %rax
movss %xmm0, 0x30a4(%rax)
jmp 0x13bc8a
movss -0xa0(%rbp), %xmm1
movq -0x38(%rbp), %rax
subss 0x30a4(%rax), %xmm1
movss -0x84(%rbp), %xmm0
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
movss 0x3631d(%rip), %xmm2    # 0x171fd8
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss 0x34f71(%rip), %xmm1    # 0x170c3c
subss -0x84(%rbp), %xmm1
divss %xmm1, %xmm0
callq 0x13bfc0
movss %xmm0, -0xa8(%rbp)
movss -0xa8(%rbp), %xmm0
movss -0x8c(%rbp), %xmm1
mulss %xmm1, %xmm0
movss 0x362d8(%rip), %xmm1    # 0x171fd8
addss %xmm1, %xmm0
cvttss2si %xmm0, %eax
cvtsi2ss %eax, %xmm0
movq -0x20(%rbp), %rax
movss %xmm0, (%rax)
movq -0x20(%rbp), %rax
movss (%rax), %xmm0
divss -0x8c(%rbp), %xmm0
callq 0x13bfc0
movss %xmm0, -0x90(%rbp)
movss -0x90(%rbp), %xmm0
movss -0x78(%rbp), %xmm1
subss -0x80(%rbp), %xmm1
mulss %xmm1, %xmm0
divss -0x78(%rbp), %xmm0
movss %xmm0, -0x94(%rbp)
testb $0x1, -0xa1(%rbp)
je 0x13bd9e
movss -0xa0(%rbp), %xmm1
subss -0x94(%rbp), %xmm1
movss -0x84(%rbp), %xmm0
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
movss 0x3624e(%rip), %xmm2    # 0x171fd8
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movq -0x38(%rbp), %rax
movss %xmm0, 0x30a4(%rax)
jmp 0x13bda0
movl $0xe, %edi
movss 0x34e8f(%rip), %xmm0    # 0x170c3c
callq 0xc76e0
movl %eax, -0xac(%rbp)
testb $0x1, -0x85(%rbp)
je 0x13bdce
movl $0x11, %eax
movl %eax, -0xf0(%rbp)
jmp 0x13bdea
movb -0x86(%rbp), %dl
movl $0xf, %eax
movl $0x10, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movl %eax, -0xf0(%rbp)
movl -0xf0(%rbp), %edi
movss -0x4c(%rbp), %xmm0
callq 0xc76e0
movl %eax, -0xb0(%rbp)
movq -0x40(%rbp), %rax
movq 0x2b8(%rax), %rdi
movq -0x10(%rbp), %rsi
movq -0x10(%rbp), %rdx
addq $0x8, %rdx
movl -0xac(%rbp), %ecx
movq -0x40(%rbp), %rax
movss 0x48(%rax), %xmm0
movl -0x2c(%rbp), %r8d
callq 0x113090
leaq -0xc0(%rbp), %rdi
callq 0xe8c60
cmpl $0x0, -0x18(%rbp)
jne 0x13bed2
movss -0x6c(%rbp), %xmm0
movss -0x64(%rbp), %xmm1
movss -0x94(%rbp), %xmm2
callq 0x13c080
movss %xmm0, -0xf4(%rbp)
movss -0x68(%rbp), %xmm0
movss %xmm0, -0xf8(%rbp)
movss -0x6c(%rbp), %xmm0
movss -0x64(%rbp), %xmm1
movss -0x94(%rbp), %xmm2
callq 0x13c080
movss -0xf8(%rbp), %xmm1
movaps %xmm0, %xmm2
movss -0xf4(%rbp), %xmm0
addss -0x80(%rbp), %xmm2
movss -0x60(%rbp), %xmm3
leaq -0xd0(%rbp), %rdi
callq 0xec090
movq -0xd0(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xc8(%rbp), %rax
movq %rax, -0xb8(%rbp)
jmp 0x13bf6a
movss -0x6c(%rbp), %xmm0
movss %xmm0, -0xfc(%rbp)
movss -0x68(%rbp), %xmm0
movss -0x60(%rbp), %xmm1
movss -0x94(%rbp), %xmm2
callq 0x13c080
movss %xmm0, -0x104(%rbp)
movss -0x64(%rbp), %xmm0
movss %xmm0, -0x100(%rbp)
movss -0x68(%rbp), %xmm0
movss -0x60(%rbp), %xmm1
movss -0x94(%rbp), %xmm2
callq 0x13c080
movss -0x104(%rbp), %xmm1
movss -0x100(%rbp), %xmm2
movaps %xmm0, %xmm3
movss -0xfc(%rbp), %xmm0
addss -0x80(%rbp), %xmm3
leaq -0xe0(%rbp), %rdi
callq 0xec090
movq -0xe0(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xd8(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0x40(%rbp), %rax
movq 0x2b8(%rax), %rdi
leaq -0xc0(%rbp), %rsi
leaq -0xc0(%rbp), %rdx
addq $0x8, %rdx
movl -0xb0(%rbp), %ecx
movq -0x58(%rbp), %rax
movss 0x74(%rax), %xmm0
movl $0xf, %r8d
callq 0x113090
movb -0x85(%rbp), %al
andb $0x1, %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x110, %rsp            # imm = 0x110
popq %rbp
retq
nopw (%rax,%rax)