// File: donfreiday[P]gb/main.cpp
// Function: main_loop()
void main_loop() {
  // Setup SDL and start new ImGui frame
  ImGui_ImplSdl_NewFrame(g_window);

  handleSdlEvents();

  // Run the emulator until vsync or breakpoint
  while ((g_running || g_stepping) && !g_gpu.vsync) {
    g_disasm.knownEntryPoints.insert(g_cpu.reg.pc);

    if (g_stepping) {
      g_stepping = false;
      g_scrollDisasmToPC = true;
    }

    g_cpu.checkInterrupts();
    g_cpu.execute();
    g_gpu.step(g_cpu.cpu_clock_t);

    // Check for breakpoint
    if (g_breakpoints.find(g_cpu.reg.pc) != g_breakpoints.end()) {
      g_running = false;
      g_scrollDisasmToPC = true;
      g_fullscreenLcd = false;
    }
  }
  g_gpu.vsync = false;

  // Render GUI windows
  imguiLCD();
  if (!g_fullscreenLcd) {
    imguiRegisters();
    imguiLcdStatus();
    imguiDisassembly();
    imguiHelp();
  }

  // ImGui::ShowTestWindow();

  // Append FPS to window title
  std::stringstream windowTitle;
  windowTitle << "gb: A Gameboy Emulator    FPS: " << std::fixed
              << std::setprecision(0) << ImGui::GetIO().Framerate;

  // Rendering
  glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x,
             (int)ImGui::GetIO().DisplaySize.y);
  glClearColor(0, 0, 0, 0);
  glClear(GL_COLOR_BUFFER_BIT);
  ImGui::Render();
  SDL_SetWindowTitle(g_window, windowTitle.str().c_str());
  SDL_GL_SwapWindow(g_window);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x230, %rsp            # imm = 0x230
movq 0x3fab6(%rip), %rdi     # 0x96f98
callq 0x4e0f0
callq 0x577e0
testb $0x1, 0x28157(%rip)     # 0x7f64a
jne 0x57506
xorl %eax, %eax
testb $0x1, 0x3fa93(%rip)     # 0x96f91
movb %al, -0x1d9(%rbp)
je 0x57514
movb 0x2ebf0(%rip), %al      # 0x860fc
xorb $-0x1, %al
movb %al, -0x1d9(%rbp)
movb -0x1d9(%rbp), %al
testb $0x1, %al
jne 0x57523
jmp 0x575e1
leaq 0x3f9de(%rip), %rdi     # 0x96f08
addq $0x28, %rdi
leaq 0x2c903(%rip), %rsi     # 0x83e38
addq $0x8, %rsi
callq 0x58ce0
movq %rax, -0x10(%rbp)
movb %dl, -0x8(%rbp)
testb $0x1, 0x3fa45(%rip)     # 0x96f91
je 0x5755c
movb $0x0, 0x3fa3c(%rip)     # 0x96f91
movb $0x1, 0x280ef(%rip)     # 0x7f64b
leaq 0x2c8d5(%rip), %rdi     # 0x83e38
callq 0x56100
leaq 0x2c8c9(%rip), %rdi     # 0x83e38
callq 0x52180
movl 0x2c8ca(%rip), %eax     # 0x83e44
leaq 0x2eb5f(%rip), %rdi     # 0x860e0
movzbl %al, %esi
callq 0x51290
leaq 0x3f9d0(%rip), %rdi     # 0x96f60
leaq 0x2c8a1(%rip), %rsi     # 0x83e38
addq $0x8, %rsi
callq 0x58d60
movq %rax, -0x18(%rbp)
leaq 0x3f9b5(%rip), %rdi     # 0x96f60
callq 0x58da0
movq %rax, -0x20(%rbp)
leaq -0x18(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x58d30
testb $0x1, %al
jne 0x575c7
jmp 0x575dc
movb $0x0, 0x2807c(%rip)     # 0x7f64a
movb $0x1, 0x28076(%rip)     # 0x7f64b
movb $0x0, 0x3f9b6(%rip)     # 0x96f92
jmp 0x574ec
movb $0x0, 0x2eb14(%rip)     # 0x860fc
callq 0x578c0
testb $0x1, 0x3f99e(%rip)     # 0x96f92
jne 0x5760a
callq 0x57b60
callq 0x57c10
callq 0x57e40
callq 0x584d0
leaq -0x1a8(%rbp), %rdi
callq 0x7230
leaq -0x198(%rbp), %rdi
leaq 0x1041c(%rip), %rsi     # 0x67a40
callq 0x7490
movq %rax, -0x1e8(%rbp)
jmp 0x57632
movq -0x1e8(%rbp), %rdi
leaq 0x1790(%rip), %rsi      # 0x58dd0
callq 0x7940
movq %rax, -0x1f0(%rbp)
jmp 0x5764e
xorl %edi, %edi
callq 0x58e00
movl %eax, -0x1f4(%rbp)
jmp 0x5765d
movq -0x1f0(%rbp), %rdi
movl -0x1f4(%rbp), %eax
movl %eax, -0x1b8(%rbp)
movl -0x1b8(%rbp), %esi
callq 0x70d0
movq %rax, -0x200(%rbp)
jmp 0x57684
callq 0xca90
movq %rax, -0x208(%rbp)
jmp 0x57692
movq -0x200(%rbp), %rdi
movq -0x208(%rbp), %rax
movss 0x328(%rax), %xmm0
callq 0x7810
jmp 0x576af
callq 0xca90
movq %rax, -0x210(%rbp)
jmp 0x576bd
movq -0x210(%rbp), %rax
cvttss2si (%rax), %eax
movl %eax, -0x21c(%rbp)
callq 0xca90
movq %rax, -0x218(%rbp)
jmp 0x576dc
movl -0x21c(%rbp), %edx
movq -0x218(%rbp), %rax
cvttss2si 0x4(%rax), %ecx
xorl %esi, %esi
movl %esi, %edi
callq 0x7360
jmp 0x576f9
xorps %xmm3, %xmm3
movaps %xmm3, %xmm0
movaps %xmm3, %xmm1
movaps %xmm3, %xmm2
callq 0x7130
jmp 0x5770c
movl $0x4000, %edi           # imm = 0x4000
callq 0x7480
jmp 0x57718
callq 0xf120
jmp 0x5771f
movq 0x3f872(%rip), %rax     # 0x96f98
movq %rax, -0x228(%rbp)
leaq -0x1d8(%rbp), %rdi
leaq -0x1a8(%rbp), %rsi
callq 0x7530
jmp 0x57742
leaq -0x1d8(%rbp), %rdi
callq 0x70e0
movq -0x228(%rbp), %rdi
movq %rax, %rsi
callq 0x7190
jmp 0x5775f
leaq -0x1d8(%rbp), %rdi
callq 0x75b0
movq 0x3f826(%rip), %rdi     # 0x96f98
callq 0x72a0
jmp 0x57779
leaq -0x1a8(%rbp), %rdi
callq 0x7320
addq $0x230, %rsp            # imm = 0x230
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b0(%rbp)
movl %eax, -0x1b4(%rbp)
jmp 0x577c0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b0(%rbp)
movl %eax, -0x1b4(%rbp)
leaq -0x1d8(%rbp), %rdi
callq 0x75b0
leaq -0x1a8(%rbp), %rdi
callq 0x7320
movq -0x1b0(%rbp), %rdi
callq 0x74f0
nopl (%rax,%rax)