// File: donfreiday[P]gb/./imgui/imgui_impl_sdl.cpp
// Function: ImGui_ImplSdl_RenderDrawLists(ImDrawData*)
void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data)
{
    // Backup GL state
    GLint last_program, last_texture, last_array_buffer, last_element_array_buffer;
    glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
    glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
    glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
    glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);

    // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
    glEnable(GL_BLEND);
    glBlendEquation(GL_FUNC_ADD);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_CULL_FACE);
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_SCISSOR_TEST);
    glActiveTexture(GL_TEXTURE0);

    // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays)
    ImGuiIO& io = ImGui::GetIO();
    float fb_height = io.DisplaySize.y * io.DisplayFramebufferScale.y;
    draw_data->ScaleClipRects(io.DisplayFramebufferScale);

    // Setup orthographic projection matrix
    const float ortho_projection[4][4] =
    {
        { 2.0f/io.DisplaySize.x, 0.0f,                   0.0f, 0.0f },
        { 0.0f,                  2.0f/-io.DisplaySize.y, 0.0f, 0.0f },
        { 0.0f,                  0.0f,                  -1.0f, 0.0f },
        {-1.0f,                  1.0f,                   0.0f, 1.0f },
    };
    glUseProgram(g_ShaderHandle);
    glUniform1i(g_AttribLocationTex, 0);
    glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);

    // Render command lists
    glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
    glEnableVertexAttribArray(g_AttribLocationPosition);
    glEnableVertexAttribArray(g_AttribLocationUV);
    glEnableVertexAttribArray(g_AttribLocationColor);

#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
    glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos));
    glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv));
    glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col));
#undef OFFSETOF
    
    for (int n = 0; n < draw_data->CmdListsCount; n++)
    {
        const ImDrawList* cmd_list = draw_data->CmdLists[n];
        const ImDrawIdx* idx_buffer_offset = 0;

        glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.size() * sizeof(ImDrawVert), (GLvoid*)&cmd_list->VtxBuffer.front(), GL_STREAM_DRAW);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.size() * sizeof(ImDrawIdx), (GLvoid*)&cmd_list->IdxBuffer.front(), GL_STREAM_DRAW);
        
        for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++)
        {
            if (pcmd->UserCallback)
            {
                pcmd->UserCallback(cmd_list, pcmd);
            }
            else
            {
                glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
                glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y));
                glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer_offset);
            }
            idx_buffer_offset += pcmd->ElemCount;
        }
    }

    // Restore modified state
    glDisableVertexAttribArray(g_AttribLocationPosition);
    glDisableVertexAttribArray(g_AttribLocationUV);
    glDisableVertexAttribArray(g_AttribLocationColor);
    glUseProgram(last_program);
    glBindTexture(GL_TEXTURE_2D, last_texture);
    glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer);
    glDisable(GL_SCISSOR_TEST);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movl $0x8b8d, %edi           # imm = 0x8B8D
leaq -0xc(%rbp), %rsi
callq 0x7690
movl $0x8069, %edi           # imm = 0x8069
leaq -0x10(%rbp), %rsi
callq 0x7690
movl $0x8894, %edi           # imm = 0x8894
leaq -0x14(%rbp), %rsi
callq 0x7690
movl $0x8895, %edi           # imm = 0x8895
leaq -0x18(%rbp), %rsi
callq 0x7690
movl $0xbe2, %edi            # imm = 0xBE2
callq 0x7470
movl $0x8006, %edi           # imm = 0x8006
callq 0x7520
movl $0x302, %edi            # imm = 0x302
movl $0x303, %esi            # imm = 0x303
callq 0x78c0
movl $0xb44, %edi            # imm = 0xB44
callq 0x7730
movl $0xb71, %edi            # imm = 0xB71
callq 0x7730
movl $0xc11, %edi            # imm = 0xC11
callq 0x7470
movl $0x84c0, %edi           # imm = 0x84C0
callq 0x7540
callq 0xca90
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movss 0x4(%rax), %xmm0
movq -0x20(%rbp), %rax
mulss 0x9c(%rax), %xmm0
movss %xmm0, -0x24(%rbp)
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
addq $0x98, %rsi
callq 0x41990
movq -0x20(%rbp), %rax
movss 0xda33(%rip), %xmm0     # 0x5b0b8
divss (%rax), %xmm0
movss %xmm0, -0x70(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x6c(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x68(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x64(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x60(%rbp)
movq -0x20(%rbp), %rax
movss 0x4(%rax), %xmm0
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm1
movss 0xd9ec(%rip), %xmm0     # 0x5b0b8
divss %xmm1, %xmm0
movss %xmm0, -0x5c(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x58(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x54(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x50(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x4c(%rbp)
movss 0xd97f(%rip), %xmm0     # 0x5b07c
movss %xmm0, -0x48(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x44(%rbp)
movss 0xd96a(%rip), %xmm0     # 0x5b07c
movss %xmm0, -0x40(%rbp)
movss 0xd8f9(%rip), %xmm0     # 0x5b018
movss %xmm0, -0x3c(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x38(%rbp)
movss 0xd8e4(%rip), %xmm0     # 0x5b018
movss %xmm0, -0x34(%rbp)
movl 0x366a9(%rip), %edi     # 0x83de8
callq 0x71f0
movl 0x366a2(%rip), %edi     # 0x83dec
xorl %esi, %esi
callq 0x76d0
movl 0x36699(%rip), %edi     # 0x83df0
leaq -0x70(%rbp), %rcx
movl $0x1, %esi
xorl %edx, %edx
callq 0x78d0
movl 0x36687(%rip), %esi     # 0x83df4
movl $0x8892, %edi           # imm = 0x8892
callq 0x75d0
movl 0x3667b(%rip), %edi     # 0x83df8
callq 0x7110
movl 0x36674(%rip), %edi     # 0x83dfc
callq 0x7110
movl 0x3666d(%rip), %edi     # 0x83e00
callq 0x7110
movl 0x3665a(%rip), %edi     # 0x83df8
movl $0x2, %esi
movl $0x1406, %edx           # imm = 0x1406
xorl %ecx, %ecx
movl $0x14, %r8d
xorl %eax, %eax
movl %eax, %r9d
callq 0x7780
movl 0x3663c(%rip), %edi     # 0x83dfc
movl $0x2, %esi
movl $0x1406, %edx           # imm = 0x1406
xorl %ecx, %ecx
movl $0x14, %r8d
xorl %eax, %eax
movl %eax, %r9d
addq $0x8, %r9
callq 0x7780
movl 0x3661a(%rip), %edi     # 0x83e00
movl $0x4, %esi
movl $0x1401, %edx           # imm = 0x1401
movl $0x1, %ecx
movl $0x14, %r8d
xorl %eax, %eax
movl %eax, %r9d
addq $0x10, %r9
callq 0x7780
movl $0x0, -0x74(%rbp)
movl -0x74(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpl 0x10(%rcx), %eax
jge 0x4da1d
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x74(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x80(%rbp)
movq $0x0, -0x88(%rbp)
movl 0x365af(%rip), %esi     # 0x83df4
movl $0x8892, %edi           # imm = 0x8892
callq 0x75d0
movq -0x80(%rbp), %rdi
addq $0x20, %rdi
callq 0x4e310
cltq
imulq $0x14, %rax, %rax
movq %rax, -0xa0(%rbp)
movq -0x80(%rbp), %rdi
addq $0x20, %rdi
callq 0x4e320
movq -0xa0(%rbp), %rsi
movq %rax, %rdx
movl $0x8892, %edi           # imm = 0x8892
movl $0x88e0, %ecx           # imm = 0x88E0
callq 0x71b0
movl 0x3656f(%rip), %esi     # 0x83e04
movl $0x8893, %edi           # imm = 0x8893
callq 0x75d0
movq -0x80(%rbp), %rdi
addq $0x10, %rdi
callq 0x4e370
cltq
shlq %rax
movq %rax, -0x98(%rbp)
movq -0x80(%rbp), %rdi
addq $0x10, %rdi
callq 0x4e380
movq -0x98(%rbp), %rsi
movq %rax, %rdx
movl $0x8893, %edi           # imm = 0x8893
movl $0x88e0, %ecx           # imm = 0x88E0
callq 0x71b0
movq -0x80(%rbp), %rdi
callq 0x4e3d0
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0x80(%rbp), %rdi
callq 0x4e3f0
movq %rax, %rcx
movq -0xa8(%rbp), %rax
cmpq %rcx, %rax
je 0x4da0d
movq -0x90(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0x4d943
movq -0x90(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x80(%rbp), %rdi
movq -0x90(%rbp), %rsi
callq *%rax
jmp 0x4d9d7
movq -0x90(%rbp), %rax
movq 0x18(%rax), %rax
movl %eax, %esi
movl $0xde1, %edi            # imm = 0xDE1
callq 0x78f0
movq -0x90(%rbp), %rax
cvttss2si 0x4(%rax), %edi
movss -0x24(%rbp), %xmm0
movq -0x90(%rbp), %rax
subss 0x10(%rax), %xmm0
cvttss2si %xmm0, %esi
movq -0x90(%rbp), %rax
movss 0xc(%rax), %xmm0
movq -0x90(%rbp), %rax
subss 0x4(%rax), %xmm0
cvttss2si %xmm0, %edx
movq -0x90(%rbp), %rax
movss 0x10(%rax), %xmm0
movq -0x90(%rbp), %rax
subss 0x8(%rax), %xmm0
cvttss2si %xmm0, %ecx
callq 0x74b0
movq -0x90(%rbp), %rax
movl (%rax), %esi
movq -0x88(%rbp), %rcx
movl $0x4, %edi
movl $0x1403, %edx           # imm = 0x1403
callq 0x7200
movq -0x90(%rbp), %rax
movl (%rax), %ecx
movq -0x88(%rbp), %rax
movl %ecx, %ecx
shlq %rcx
addq %rcx, %rax
movq %rax, -0x88(%rbp)
movq -0x90(%rbp), %rax
addq $0x30, %rax
movq %rax, -0x90(%rbp)
jmp 0x4d8ee
jmp 0x4da0f
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0x4d810
movl 0x363d5(%rip), %edi     # 0x83df8
callq 0x7620
movl 0x363ce(%rip), %edi     # 0x83dfc
callq 0x7620
movl 0x363c7(%rip), %edi     # 0x83e00
callq 0x7620
movl -0xc(%rbp), %edi
callq 0x71f0
movl -0x10(%rbp), %esi
movl $0xde1, %edi            # imm = 0xDE1
callq 0x78f0
movl -0x14(%rbp), %esi
movl $0x8892, %edi           # imm = 0x8892
callq 0x75d0
movl -0x18(%rbp), %esi
movl $0x8893, %edi           # imm = 0x8893
callq 0x75d0
movl $0xc11, %edi            # imm = 0xC11
callq 0x7730
addq $0xb0, %rsp
popq %rbp
retq