// File: /workspace/github_cpp_makefile_star2_O2/Ciaxur[P]yagb-emu/include/imgui/imgui_widgets.cpp
// Function: bool ImGui::DragBehaviorT<unsigned long long, long long, double>(int, unsigned long long*, float, unsigned long long, unsigned long long, char const*, int)
bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const TYPE v_min, const TYPE v_max, const char* format, ImGuiSliderFlags flags)
{
    ImGuiContext& g = *GImGui;
    const ImGuiAxis axis = (flags & ImGuiSliderFlags_Vertical) ? ImGuiAxis_Y : ImGuiAxis_X;
    const bool is_decimal = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double);
    const bool is_clamped = (v_min < v_max);
    const bool is_logarithmic = (flags & ImGuiSliderFlags_Logarithmic) && is_decimal;

    // Default tweak speed
    if (v_speed == 0.0f && is_clamped && (v_max - v_min < FLT_MAX))
        v_speed = (float)((v_max - v_min) * g.DragSpeedDefaultRatio);

    // Inputs accumulates into g.DragCurrentAccum, which is flushed into the current value as soon as it makes a difference with our precision settings
    float adjust_delta = 0.0f;
    if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid() && IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR))
    {
        adjust_delta = g.IO.MouseDelta[axis];
        if (g.IO.KeyAlt)
            adjust_delta *= 1.0f / 100.0f;
        if (g.IO.KeyShift)
            adjust_delta *= 10.0f;
    }
    else if (g.ActiveIdSource == ImGuiInputSource_Nav)
    {
        int decimal_precision = is_decimal ? ImParseFormatPrecision(format, 3) : 0;
        adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f / 10.0f, 10.0f)[axis];
        v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision));
    }
    adjust_delta *= v_speed;

    // For vertical drag we currently assume that Up=higher value (like we do with vertical sliders). This may become a parameter.
    if (axis == ImGuiAxis_Y)
        adjust_delta = -adjust_delta;

    // For logarithmic use our range is effectively 0..1 so scale the delta into that range
    if (is_logarithmic && (v_max - v_min < FLT_MAX) && ((v_max - v_min) > 0.000001f)) // Epsilon to avoid /0
        adjust_delta /= (float)(v_max - v_min);

    // Clear current value on activation
    // Avoid altering values and clamping when we are _already_ past the limits and heading in the same direction, so e.g. if range is 0..255, current value is 300 and we are pushing to the right side, keep the 300.
    bool is_just_activated = g.ActiveIdIsJustActivated;
    bool is_already_past_limits_and_pushing_outward = is_clamped && ((*v >= v_max && adjust_delta > 0.0f) || (*v <= v_min && adjust_delta < 0.0f));
    if (is_just_activated || is_already_past_limits_and_pushing_outward)
    {
        g.DragCurrentAccum = 0.0f;
        g.DragCurrentAccumDirty = false;
    }
    else if (adjust_delta != 0.0f)
    {
        g.DragCurrentAccum += adjust_delta;
        g.DragCurrentAccumDirty = true;
    }

    if (!g.DragCurrentAccumDirty)
        return false;

    TYPE v_cur = *v;
    FLOATTYPE v_old_ref_for_accum_remainder = (FLOATTYPE)0.0f;

    float logarithmic_zero_epsilon = 0.0f; // Only valid when is_logarithmic is true
    const float zero_deadzone_halfsize = 0.0f; // Drag widgets have no deadzone (as it doesn't make sense)
    if (is_logarithmic)
    {
        // When using logarithmic sliders, we need to clamp to avoid hitting zero, but our choice of clamp value greatly affects slider precision. We attempt to use the specified precision to estimate a good lower bound.
        const int decimal_precision = is_decimal ? ImParseFormatPrecision(format, 3) : 1;
        logarithmic_zero_epsilon = ImPow(0.1f, (float)decimal_precision);

        // Convert to parametric space, apply delta, convert back
        float v_old_parametric = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, v_cur, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
        float v_new_parametric = v_old_parametric + g.DragCurrentAccum;
        v_cur = ScaleValueFromRatioT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, v_new_parametric, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
        v_old_ref_for_accum_remainder = v_old_parametric;
    }
    else
    {
        v_cur += (SIGNEDTYPE)g.DragCurrentAccum;
    }

    // Round to user desired precision based on format string
    if (!(flags & ImGuiSliderFlags_NoRoundToFormat))
        v_cur = RoundScalarWithFormatT<TYPE, SIGNEDTYPE>(format, data_type, v_cur);

    // Preserve remainder after rounding has been applied. This also allow slow tweaking of values.
    g.DragCurrentAccumDirty = false;
    if (is_logarithmic)
    {
        // Convert to parametric space, apply delta, convert back
        float v_new_parametric = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, v_cur, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
        g.DragCurrentAccum -= (float)(v_new_parametric - v_old_ref_for_accum_remainder);
    }
    else
    {
        g.DragCurrentAccum -= (float)((SIGNEDTYPE)v_cur - (SIGNEDTYPE)*v);
    }

    // Lose zero sign for float/double
    if (v_cur == (TYPE)-0)
        v_cur = (TYPE)0;

    // Clamp values (+ handle overflow/wrap-around for integer types)
    if (*v != v_cur && is_clamped)
    {
        if (v_cur < v_min || (v_cur > *v && adjust_delta < 0.0f && !is_decimal))
            v_cur = v_min;
        if (v_cur > v_max || (v_cur < *v && adjust_delta > 0.0f && !is_decimal))
            v_cur = v_max;
    }

    // Apply result
    if (*v == v_cur)
        return false;
    *v = v_cur;
    return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movl %r9d, %r12d
movq %r8, -0x70(%rbp)
movq %rcx, %r14
movaps %xmm0, %xmm2
movq %rsi, %r15
leaq 0x5465e(%rip), %rax     # 0xe3ce0
movq (%rax), %rsi
movl %r9d, %r13d
andl $0x100000, %r13d        # imm = 0x100000
movl %edi, -0x44(%rbp)
movl %edi, %eax
andl $-0x2, %eax
movl %eax, -0x48(%rbp)
cmpl $0x8, %eax
sete %dil
movq %rcx, -0x80(%rbp)
movq %rdx, -0x68(%rbp)
subq %rdx, %r14
setbe %al
movl %r9d, -0x74(%rbp)
andl $0x20, %r12d
xorps %xmm0, %xmm0
ucomiss %xmm0, %xmm2
setp %cl
setne %dl
orb %cl, %dl
orb %al, %dl
jne 0x8f6f5
testq %r14, %r14
js 0x8f6d5
cvtsi2ss %r14, %xmm2
jmp 0x8f6ed
movq %r14, %rax
shrq %rax
movl %r14d, %ecx
andl $0x1, %ecx
orq %rax, %rcx
cvtsi2ss %rcx, %xmm2
addss %xmm2, %xmm2
mulss 0x30a0(%rsi), %xmm2
movb %dil, -0x2c(%rbp)
shrl $0x5, %r12d
movl %r13d, %ebx
shrl $0x14, %ebx
movl 0x1b68(%rsi), %eax
cmpl $0x1, %eax
movq %rsi, -0x40(%rbp)
movaps %xmm2, -0x60(%rbp)
jne 0x8f7a3
xorl %edi, %edi
callq 0x381f3
testb %al, %al
je 0x8f795
movq -0x40(%rbp), %rax
movss 0x38(%rax), %xmm0
mulss 0xc8e2(%rip), %xmm0     # 0x9c018
xorl %edi, %edi
callq 0x402c5
testb %al, %al
je 0x8f795
movq %r15, -0x38(%rbp)
movq -0x40(%rbp), %r15
leaq 0x3b8(%r15), %rdi
movl %ebx, %esi
callq 0x8e818
movq %r15, %rsi
movss (%rax), %xmm3
cmpb $0x0, 0x142(%r15)
je 0x8f770
mulss 0x12ab4(%rip), %xmm3    # 0xa2224
movb -0x2c(%rbp), %bl
movq -0x38(%rbp), %r15
movaps -0x60(%rbp), %xmm2
cmpb $0x1, 0x141(%rsi)
jne 0x8f82d
mulss 0xc88c(%rip), %xmm3     # 0x9c01c
jmp 0x8f82d
movq -0x40(%rbp), %rsi
movl 0x1b68(%rsi), %eax
movaps -0x60(%rbp), %xmm2
xorps %xmm3, %xmm3
cmpl $0x2, %eax
jne 0x8f82a
movq %r15, -0x38(%rbp)
xorl %r15d, %r15d
cmpl $0x8, -0x48(%rbp)
jne 0x8f7c7
pushq $0x3
popq %rsi
movq -0x70(%rbp), %rdi
callq 0x80ac1
movl %eax, %r15d
pushq $0x3
popq %rdi
pushq $0x5
popq %rsi
movss 0xd0df(%rip), %xmm0     # 0x9c8b4
movss 0xc83f(%rip), %xmm1     # 0x9c01c
callq 0x457c8
leaq -0x98(%rbp), %rdi
movlps %xmm0, (%rdi)
movl %ebx, %esi
callq 0x8e818
movss (%rax), %xmm0
movaps %xmm0, -0x90(%rbp)
movl %r15d, %edi
callq 0x8e790
movaps -0x90(%rbp), %xmm3
movaps %xmm0, %xmm1
movaps -0x60(%rbp), %xmm2
cmpless %xmm2, %xmm1
andps %xmm1, %xmm2
andnps %xmm0, %xmm1
orps %xmm1, %xmm2
movq -0x38(%rbp), %r15
movq -0x40(%rbp), %rsi
movb -0x2c(%rbp), %bl
mulss %xmm2, %xmm3
testl %r13d, %r13d
je 0x8f83d
xorps 0xc7a3(%rip), %xmm3     # 0x9bfe0
andb %r12b, %bl
testq %r14, %r14
js 0x8f84c
cvtsi2ss %r14, %xmm0
jmp 0x8f862
movq %r14, %rax
shrq %rax
andl $0x1, %r14d
orq %rax, %r14
cvtsi2ss %r14, %xmm0
addss %xmm0, %xmm0
movq -0x68(%rbp), %r12
testb %bl, %bl
movq -0x80(%rbp), %r14
movaps %xmm3, %xmm1
je 0x8f875
divss %xmm0, %xmm1
xorl %ecx, %ecx
cmpq %r12, %r14
jne 0x8f87f
movaps %xmm3, %xmm1
movb 0x1b3c(%rsi), %al
jbe 0x8f8a8
movq (%r15), %rcx
cmpq %r14, %rcx
jb 0x8f897
xorps %xmm0, %xmm0
ucomiss %xmm0, %xmm1
ja 0x8f8d7
cmpq %r12, %rcx
setbe %dl
xorps %xmm0, %xmm0
ucomiss %xmm1, %xmm0
seta %cl
andb %dl, %cl
testb %al, %al
jne 0x8f8d7
testb %cl, %cl
jne 0x8f8d7
xorps %xmm0, %xmm0
ucomiss %xmm0, %xmm1
jne 0x8f8ba
jnp 0x8f8f6
movss 0x309c(%rsi), %xmm0
addss %xmm1, %xmm0
movss %xmm0, 0x309c(%rsi)
movb $0x1, 0x3099(%rsi)
jmp 0x8f8ff
andl $0x0, 0x309c(%rsi)
movb $0x0, 0x3099(%rsi)
xorl %eax, %eax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testb $0x1, 0x3099(%rsi)
je 0x8f8e5
movq %r15, -0x38(%rbp)
movq (%r15), %r15
testb %bl, %bl
movss %xmm1, -0x68(%rbp)
je 0x8f98e
pushq $0x3
popq %rsi
movq -0x70(%rbp), %rdi
callq 0x80ac1
cvtsi2ss %eax, %xmm1
movss 0xcf8d(%rip), %xmm0     # 0x9c8b4
callq 0xc770
movss %xmm0, -0x2c(%rbp)
pushq $0x1
popq %r8
xorps %xmm1, %xmm1
movl %ebx, %r13d
movl -0x44(%rbp), %ebx
movl %ebx, %edi
movq %r15, %rsi
movq %r12, %rdx
movq %r14, %rcx
movl %r8d, %r15d
callq 0x941c4
movaps %xmm0, %xmm1
movss %xmm0, -0x60(%rbp)
movq -0x40(%rbp), %rax
movss 0x309c(%rax), %xmm0
addss %xmm1, %xmm0
xorps %xmm2, %xmm2
movl %ebx, %edi
movl %r13d, %ebx
movq %r12, %rsi
movq %r14, %rdx
movl %r15d, %ecx
movss -0x2c(%rbp), %xmm1
callq 0x94306
movq %rax, %r15
cvtss2sd -0x60(%rbp), %xmm0
jmp 0x8f9a5
cvttss2si 0x309c(%rsi), %rax
addq %rax, %r15
xorps %xmm0, %xmm0
movss %xmm0, -0x2c(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x60(%rbp)
testb $0x40, -0x74(%rbp)
jne 0x8f9c2
movq -0x70(%rbp), %rdi
movl -0x44(%rbp), %esi
movq %r15, %rdx
callq 0x9449f
movq %rax, %r15
movq -0x40(%rbp), %rdx
movb $0x0, 0x3099(%rdx)
testb %bl, %bl
je 0x8fa1d
pushq $0x1
popq %r8
xorps %xmm1, %xmm1
movl -0x44(%rbp), %edi
movq %rdx, %r13
movq %r15, %rsi
movq %r12, %rdx
movq %r14, %rcx
movss -0x2c(%rbp), %xmm0
callq 0x941c4
cvtss2sd %xmm0, %xmm0
subsd -0x60(%rbp), %xmm0
cvtsd2ss %xmm0, %xmm0
movss 0x309c(%r13), %xmm1
subss %xmm0, %xmm1
movss %xmm1, 0x309c(%r13)
movq -0x38(%rbp), %rax
movq (%rax), %rax
jmp 0x8fa43
movq -0x38(%rbp), %rax
movq (%rax), %rax
movq %r15, %rcx
subq %rax, %rcx
cvtsi2ss %rcx, %xmm0
movss 0x309c(%rdx), %xmm1
subss %xmm0, %xmm1
movss %xmm1, 0x309c(%rdx)
cmpq %r12, %r14
movss -0x68(%rbp), %xmm1
jbe 0x8fa88
cmpq %r15, %rax
je 0x8fa88
cmpq %r12, %r15
jb 0x8fa6a
cmpl $0x8, -0x48(%rbp)
je 0x8fa6d
cmpq %rax, %r15
jbe 0x8fa6d
xorps %xmm0, %xmm0
ucomiss %xmm1, %xmm0
jbe 0x8fa6d
movq %r12, %r15
cmpq %r14, %r15
ja 0x8fa85
cmpl $0x8, -0x48(%rbp)
je 0x8fa88
cmpq %rax, %r15
jae 0x8fa88
xorps %xmm0, %xmm0
ucomiss %xmm0, %xmm1
jbe 0x8fa88
movq %r14, %r15
cmpq %r15, %rax
je 0x8f8e5
movq -0x38(%rbp), %rax
movq %r15, (%rax)
movb $0x1, %al
jmp 0x8f8e7