// File: /workspace/github_cpp_makefile_star2_O3/therealgymmy[P]HelicopterGame/src/events.cpp
// Function: events(void*)
void pollForEvents (EventsArg *eventsArg) {
    Resources       *resources = eventsArg->resources_;
    XHandler        *xhandler  = eventsArg->xhandler_;
    pthread_mutex_t *mutex     = eventsArg->mutex_;

    Display *display = xhandler->display();
    Window   window  = xhandler->window();
    XSelectInput(display, window,
                 KeyPressMask |
                 KeyReleaseMask |
                 StructureNotifyMask);

    Helicopter &helicopter = resources->heli_;
    KeySym key;
    XWindowAttributes attr;

    XEvent event;
    while (true) {
        XNextEvent(display, &event);

        if (pthread_mutex_lock(mutex) == -1) {
            error("cannot lock mutex in control thread");
        }

        switch (event.type) {
            case ConfigureNotify:
                if (event.xconfigure.width  != attr.width ||
                        event.xconfigure.height != attr.height) {
                    XGetWindowAttributes(display, window, &attr);

                    attr::DrawableBase::ScaleX = (double)PLANE_W / (double)attr.width;
                    attr::DrawableBase::ScaleY = (double)PLANE_H / (double)attr.height;

                    std::cout << attr::DrawableBase::ScaleX << std::endl;
                    std::cout << attr::DrawableBase::ScaleY << std::endl;
                    std::cout << "w: " << attr.width << std::endl;
                    std::cout << "h: " << attr.height << std::endl;

                    xhandler->updateAttr(&attr);
                }

                break;

            case KeyPress:
                XLookupString(&event.xkey, NULL, 0, &key, NULL);
                switch (key) {
                    case XK_f:
                        if (xhandler->showCredit()) {
                            xhandler->setShowCredit(false);
                        }
                        else {
                            xhandler->setShowCredit(true);
                        }
                        break;

                    case XK_Up:
                        helicopter.up_ = true;
                        break;
                    case XK_Down:
                        helicopter.down_ = true;
                        break;
                    case XK_Left:
                        helicopter.left_ = true;
                        break;
                    case XK_Right:
                        helicopter.right_ = true;
                        break;

                    case XK_a:
                        Tower::incSpeed();
                        Missile::incSpeed();
                        break;
                    case XK_z:
                        Tower::decSpeed();
                        Missile::decSpeed();
                        break;

                    /*
                    case XK_q:  // slow down scroll speed
                        Tower::incDelay(1);
                        Missile::incDelay(1);
                        Bomb::incDelay(2);
                        break;
                    case XK_w:  // speed up scroll speed
                        Tower::decDelay(1);
                        Missile::decDelay(1);
                        Bomb::decDelay(2);
                        break;

                    */
                    case XK_d:
                        if (helicopter.right_) {
                            int x = helicopter.x() + helicopter.w() * 0.8;
                            int y = helicopter.y() + helicopter.h() * 0.8;
                            resources->bombs_.addBomb(x,
                                                      y,
                                                      Bomb::FORWARD);
                        }
                        else if (helicopter.left_) {
                            int x = helicopter.x() + helicopter.w() * 0.8;
                            int y = helicopter.y() + helicopter.h() * 0.8;
                            resources->bombs_.addBomb(x,
                                                      y,
                                                      Bomb::BACKWARD);
                        }
                        else {
                            int x = helicopter.x() + helicopter.w() * 0.8;
                            int y = helicopter.y() + helicopter.h() * 0.8;
                            resources->bombs_.addBomb(x,
                                                      y,
                                                      Bomb::NUL);
                        }

                        /*
                        if (helicopter.movement() == Helicopter::LEFT) {
                            resources->bombs_.push_back(
                                    Bomb(
                                        helicopter.x() + Helicopter::w(),
                                        helicopter.y() + Helicopter::h(),
                                        false));
                        }
                        else {
                            resources->bombs_.push_back(
                                    Bomb(
                                        helicopter.x() + Helicopter::w(),
                                        helicopter.y() + Helicopter::h(),
                                        true));
                        }
                        */
                        break;

                    default:
                        break;
                }
                break;

            case KeyRelease:
                XLookupString(&event.xkey, NULL, 0, &key, NULL);
                switch (key) {
                    case XK_Up:
                        helicopter.up_ = false;
                        helicopter.delayUp_ = 30;
                        break;
                    case XK_Down:
                        helicopter.down_ = false;
                        helicopter.delayDown_ = 30;
                        break;
                    case XK_Left:
                        helicopter.left_ = false;
                        helicopter.delayLeft_ = 30;
                        break;
                    case XK_Right:
                        helicopter.right_ = false;
                        helicopter.delayRight_ = 30;
                        break;
                    default:
                        break;
                }
                break;

            default:
                break;

        }

        if (pthread_mutex_unlock(mutex) == -1) {
            error("cannot unlock mutex in control thread");
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x198, %rsp            # imm = 0x198
movq (%rdi), %rbx
movq 0x8(%rdi), %rax
movq 0x10(%rdi), %r15
movq 0x8(%rax), %rbp
movq %rax, 0x8(%rsp)
movq 0x18(%rax), %rsi
movl $0x20003, %edx          # imm = 0x20003
movq %rbp, %rdi
movq %rsi, 0x20(%rsp)
callq 0x2100
leaq 0xd8(%rsp), %r13
leaq 0x10(%rsp), %r14
movq %rbp, 0x18(%rsp)
movq %rbp, %rdi
movq %r13, %rsi
callq 0x2290
movq %r15, %rdi
callq 0x22a0
cmpl $-0x1, %eax
je 0x48ba
movl 0xd8(%rsp), %eax
cmpl $0x2, %eax
je 0x4615
cmpl $0x3, %eax
je 0x45ca
cmpl $0x16, %eax
jne 0x4830
movl 0x110(%rsp), %eax
cmpl 0x58(%rsp), %eax
jne 0x4441
movl 0x114(%rsp), %eax
cmpl 0x5c(%rsp), %eax
je 0x4830
movq %rbp, %rdi
movq 0x20(%rsp), %rsi
leaq 0x50(%rsp), %rdx
callq 0x2360
xorps %xmm1, %xmm1
cvtsi2sdl 0x58(%rsp), %xmm1
movsd 0x1bbc(%rip), %xmm0     # 0x6020
divsd %xmm1, %xmm0
xorps %xmm1, %xmm1
cvtsi2sdl 0x5c(%rsp), %xmm1
leaq 0x4d90(%rip), %rax      # 0x9208
movsd %xmm0, (%rax)
movsd 0x1ba4(%rip), %xmm2     # 0x6028
divsd %xmm1, %xmm2
leaq 0x4d81(%rip), %r13      # 0x9210
movsd %xmm2, (%r13)
movq 0x4b34(%rip), %r12      # 0x8fd0
movq %r12, %rdi
callq 0x2320
movq %rbx, %rbp
movq %r14, %rbx
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21d0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2110
movsd (%r13), %xmm0
movq %r12, %rdi
callq 0x2320
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21d0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2110
movl $0x3, %edx
movq %r12, %rdi
leaq 0x1d51(%rip), %rsi      # 0x626c
callq 0x2210
movl 0x58(%rsp), %esi
movq %r12, %rdi
callq 0x2340
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21d0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2110
movl $0x3, %edx
movq %r12, %rdi
leaq 0x1d0b(%rip), %rsi      # 0x6270
callq 0x2210
movl 0x5c(%rsp), %esi
movq %r12, %rdi
callq 0x2340
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21d0
movsbl %al, %esi
movq %r14, %rdi
movq 0x8(%rsp), %r12
movq %rbx, %r14
movq %rbp, %rbx
leaq 0xd8(%rsp), %r13
movq 0x18(%rsp), %rbp
callq 0x2030
movq %rax, %rdi
callq 0x2110
movq %r12, %rdi
leaq 0x50(%rsp), %rsi
callq 0x40d0
jmp 0x4830
movq %r13, %rdi
xorl %esi, %esi
xorl %edx, %edx
movq %r14, %rcx
xorl %r8d, %r8d
callq 0x21a0
movq 0x10(%rsp), %rax
movq $-0xff51, %rcx          # imm = 0xFFFF00AF
addq %rcx, %rax
cmpq $0x3, %rax
ja 0x4830
leaq 0x1c2c(%rip), %rcx      # 0x6228
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movb $0x0, 0x3a(%rbx)
movl $0x1e, 0x44(%rbx)
jmp 0x4830
movq %r13, %rdi
xorl %esi, %esi
xorl %edx, %edx
movq %r14, %rcx
xorl %r8d, %r8d
callq 0x21a0
movq 0x10(%rsp), %rax
cmpq $0x79, %rax
jg 0x4673
cmpq $0x61, %rax
je 0x46cd
cmpq $0x64, %rax
je 0x46ff
cmpq $0x66, %rax
jne 0x4830
movq 0x8(%rsp), %rax
cmpb $0x1, 0xf0(%rax)
jne 0x47bc
movq 0x8(%rsp), %rax
movb $0x0, 0xf0(%rax)
jmp 0x4830
leaq -0xff51(%rax), %rcx
cmpq $0x3, %rcx
ja 0x4762
leaq 0x1bad(%rip), %rdx      # 0x6238
movslq (%rdx,%rcx,4), %rax
addq %rdx, %rax
jmpq *%rax
movb $0x1, 0x3a(%rbx)
jmp 0x4830
movb $0x0, 0x3b(%rbx)
movl $0x1e, 0x48(%rbx)
jmp 0x4830
movb $0x0, 0x39(%rbx)
movl $0x1e, 0x40(%rbx)
jmp 0x4830
movb $0x0, 0x38(%rbx)
movl $0x1e, 0x3c(%rbx)
jmp 0x4830
leaq 0x4b2c(%rip), %rax      # 0x9200
movl (%rax), %eax
cmpl $0x9, %eax
jg 0x46e6
incl %eax
leaq 0x4b1c(%rip), %rcx      # 0x9200
movl %eax, (%rcx)
leaq 0x4b3b(%rip), %rax      # 0x9228
movl (%rax), %eax
cmpl $0x9, %eax
jg 0x4830
incl %eax
jmp 0x4799
cmpb $0x1, 0x3b(%rbx)
jne 0x47ca
xorps %xmm0, %xmm0
cvtsi2sdl 0x4c(%rbx), %xmm0
leaq 0x4b2c(%rip), %rax      # 0x9244
xorps %xmm1, %xmm1
cvtsi2sdl (%rax), %xmm1
movsd 0x1af9(%rip), %xmm2     # 0x6220
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
cvttsd2si %xmm1, %esi
xorps %xmm0, %xmm0
cvtsi2sdl 0x50(%rbx), %xmm0
leaq 0x4b06(%rip), %rax      # 0x9248
xorps %xmm1, %xmm1
cvtsi2sdl (%rax), %xmm1
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
cvttsd2si %xmm1, %edx
movq %rbx, %rdi
movl $0x1, %ecx
jmp 0x482b
cmpq $0x7a, %rax
jne 0x4830
leaq 0x4a8d(%rip), %rax      # 0x9200
movl (%rax), %eax
cmpl $0x2, %eax
jl 0x4785
decl %eax
leaq 0x4a7d(%rip), %rcx      # 0x9200
movl %eax, (%rcx)
leaq 0x4a9c(%rip), %rax      # 0x9228
movl (%rax), %eax
cmpl $0x2, %eax
jl 0x4830
decl %eax
leaq 0x4a88(%rip), %rcx      # 0x9228
movl %eax, (%rcx)
jmp 0x4830
movb $0x1, 0x3b(%rbx)
jmp 0x4830
movb $0x1, 0x39(%rbx)
jmp 0x4830
movb $0x1, 0x38(%rbx)
jmp 0x4830
movq 0x8(%rsp), %rax
movb $0x1, 0xf0(%rax)
jmp 0x4830
xorps %xmm0, %xmm0
cvtsi2sdl 0x4c(%rbx), %xmm0
leaq 0x4a6b(%rip), %rax      # 0x9244
xorps %xmm1, %xmm1
cvtsi2sdl (%rax), %xmm1
movsd 0x1a38(%rip), %xmm2     # 0x6220
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
cvttsd2si %xmm1, %esi
xorps %xmm0, %xmm0
cvtsi2sdl 0x50(%rbx), %xmm0
leaq 0x4a45(%rip), %rax      # 0x9248
xorps %xmm1, %xmm1
cvtsi2sdl (%rax), %xmm1
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
cvttsd2si %xmm1, %edx
cmpb $0x1, 0x3a(%rbx)
jne 0x4826
movq %rbx, %rdi
movl $0x2, %ecx
jmp 0x482b
movq %rbx, %rdi
xorl %ecx, %ecx
callq 0x5684
movq %r15, %rdi
callq 0x2160
cmpl $-0x1, %eax
jne 0x43e5
leaq 0x40(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x28(%rsp), %rbx
movq $0x25, (%rbx)
leaq 0x30(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x2380
movq %rax, (%r14)
movq (%rbx), %rcx
movq %rcx, 0x10(%r14)
movabsq $0x646165726874206c, %rdx # imm = 0x646165726874206C
movq %rdx, 0x1d(%rax)
movups 0x19fd(%rip), %xmm0     # 0x6284
movups %xmm0, 0x10(%rax)
movups 0x19e2(%rip), %xmm0     # 0x6274
movups %xmm0, (%rax)
movq %rcx, 0x8(%r14)
movb $0x0, (%rax,%rcx)
movq (%r14), %rsi
movq 0x8(%r14), %rdx
movq 0x4745(%rip), %rdi      # 0x8ff0
callq 0x2210
movq %rax, %rdi
callq 0x20c0
jmp 0x492a
leaq 0x40(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x28(%rsp), %rbx
movq $0x23, (%rbx)
leaq 0x30(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x2380
movq %rax, (%r14)
movq (%rbx), %rcx
movq %rcx, 0x10(%r14)
movups 0x1966(%rip), %xmm0     # 0x6258
movups %xmm0, 0x10(%rax)
movups 0x194b(%rip), %xmm0     # 0x6248
movups %xmm0, (%rax)
movl $0x64616572, 0x1f(%rax) # imm = 0x64616572
movq %rcx, 0x8(%r14)
movb $0x0, (%rax,%rcx)
movq (%r14), %rsi
movq 0x8(%r14), %rdx
movq 0x46d3(%rip), %rdi      # 0x8ff0
callq 0x2210
movq %rax, %rdi
callq 0x20c0
movl $0x1, %edi
callq 0x2230
jmp 0x4936
movq %rax, %rbx
movq 0x30(%rsp), %rdi
cmpq %r15, %rdi
je 0x494e
movq (%r15), %rsi
incq %rsi
callq 0x2200
movq %rbx, %rdi
callq 0x2350
nop