// File: /workspace/github_cpp_makefile_star2_O2/disjukr[P]Tetris/Tetris.cc
// Function: Tetris::Loop()
void Tetris::Loop() {
    if (Keyboard::hit()) {
        switch(Keyboard::code()) {
        case UP: case W:
            this -> ControlPiece([this]() {
                currentPiece -> RotateCW();
            });
            break;
        case X: case Q:
            this -> ControlPiece([this]() {
                currentPiece -> RotateCCW();
            });
            break;
        case LEFT: case A:
            this -> ControlPiece([this]() {
                --(currentPiece -> x);
            });
            break;
        case RIGHT: case D:
            this -> ControlPiece([this]() {
                ++(currentPiece -> x);
            });
            break;
        case DOWN: case S:
            this -> SoftDrop();
            ++statistics.score;
            break;
        case SPACE: case F:
            this -> HardDrop();
            break;
        case C: case R:
            this -> HardDrop(false);
            break;
        case Z: case E:
            this -> HoldPiece();
            break;
        case ESC:
            this -> Exit();
            return;
        default:
            break;
        }
    }
    int frameDiff = (int) (frame - lastDrop);
    if (dropFrameInterval < frameDiff) {
        if (this -> SoftDrop(attachFrameInterval < frameDiff))
            lastDrop = frame;
    }
    if (this -> CheckGameOver()) {
        this -> Exit();
        return;
    }
    int lineCount = 0;
    for (int i = 0; i < TetrisStage::height; ++i) {
        if (this -> CheckLine(i)) {
            this -> stage.EraseLine(i);
            ++lineCount;
        }
    }
    switch (lineCount) {
    case 1: ++statistics._single; statistics.score += 100; break;
    case 2: ++statistics._double; statistics.score += 300; break;
    case 3: ++statistics._triple; statistics.score += 500; break;
    case 4: ++statistics._tetris; statistics.score += 800; break;
    }
    if (statistics.score > statistics.level * 1000)
        LevelUp();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x80, %rsp
movq %rdi, %rbx
callq 0x6a78
testb %al, %al
je 0x3eca
callq 0x6a84
cmpl $0x10, %eax
ja 0x3eca
movl %eax, %eax
leaq 0x3263(%rip), %rcx      # 0x7018
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq -0xa0(%rbp), %r14
andq $0x0, 0x8(%r14)
movq %rbx, (%r14)
leaq 0xfcc(%rip), %rax       # 0x4da0
movq %rax, 0x18(%r14)
leaq 0xfd7(%rip), %rax       # 0x4db6
movq %rax, 0x10(%r14)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3fdc
leaq -0xa0(%rbp), %rdi
jmp 0x3eb5
leaq -0x80(%rbp), %r14
andq $0x0, 0x8(%r14)
movq %rbx, (%r14)
leaq 0xfd3(%rip), %rax       # 0x4de0
movq %rax, 0x18(%r14)
leaq 0xfde(%rip), %rax       # 0x4df6
movq %rax, 0x10(%r14)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3fdc
leaq -0x80(%rbp), %rdi
jmp 0x3eb5
pushq $0x1
popq %rsi
movq %rbx, %rdi
jmp 0x3e4a
movq %rbx, %rdi
callq 0x40da
jmp 0x3eca
movq %rbx, %rdi
xorl %esi, %esi
callq 0x409e
jmp 0x3eca
leaq -0x60(%rbp), %r14
andq $0x0, 0x8(%r14)
movq %rbx, (%r14)
leaq 0xfbc(%rip), %rax       # 0x4e20
movq %rax, 0x18(%r14)
leaq 0xfc5(%rip), %rax       # 0x4e34
movq %rax, 0x10(%r14)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3fdc
leaq -0x60(%rbp), %rdi
jmp 0x3eb5
leaq -0x40(%rbp), %r14
andq $0x0, 0x8(%r14)
movq %rbx, (%r14)
leaq 0xfc7(%rip), %rax       # 0x4e5e
movq %rax, 0x18(%r14)
leaq 0xfd0(%rip), %rax       # 0x4e72
movq %rax, 0x10(%r14)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3fdc
leaq -0x40(%rbp), %rdi
callq 0x4f8c
jmp 0x3eca
pushq $0x1
popq %rsi
movq %rbx, %rdi
callq 0x404a
incl 0x20(%rbx)
movl 0xc(%rbx), %eax
subl 0x1c(%rbx), %eax
cmpl %eax, 0x14(%rbx)
jge 0x3ef0
xorl %esi, %esi
cmpl %eax, 0x18(%rbx)
setl %sil
movq %rbx, %rdi
callq 0x404a
testb %al, %al
je 0x3ef0
movl 0xc(%rbx), %eax
movl %eax, 0x1c(%rbx)
movq %rbx, %rdi
callq 0x4134
testb %al, %al
je 0x3f0a
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x10(%rax)
jmp 0x3f95
leaq 0x38(%rbx), %r14
xorl %r12d, %r12d
xorl %r15d, %r15d
cmpl $0x16, %r15d
je 0x3f3c
movq %rbx, %rdi
movl %r15d, %esi
callq 0x4158
testb %al, %al
je 0x3f37
movq %r14, %rdi
movl %r15d, %esi
callq 0x418c
incl %r12d
incl %r15d
jmp 0x3f14
decl %r12d
cmpl $0x3, %r12d
ja 0x3fa5
leaq 0x3110(%rip), %rax      # 0x705c
movslq (%rax,%r12,4), %rcx
addq %rax, %rcx
jmpq *%rcx
incl 0x28(%rbx)
movl 0x20(%rbx), %eax
addl $0x64, %eax
jmp 0x3f7f
incl 0x30(%rbx)
movl $0x1f4, %eax            # imm = 0x1F4
jmp 0x3f7c
incl 0x34(%rbx)
movl $0x320, %eax            # imm = 0x320
jmp 0x3f7c
incl 0x2c(%rbx)
movl $0x12c, %eax            # imm = 0x12C
addl 0x20(%rbx), %eax
movl %eax, 0x20(%rbx)
imull $0x3e8, 0x24(%rbx), %ecx # imm = 0x3E8
cmpl %ecx, %eax
jle 0x3f95
movq %rbx, %rdi
callq 0x41d8
addq $0x80, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movl 0x20(%rbx), %eax
jmp 0x3f82
movq (%rbx), %rax
movq %rbx, %rdi
addq $0x80, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmpq *0x10(%rax)
jmp 0x3fc8
jmp 0x3fc8
jmp 0x3fc8
movq %rax, %rbx
movq %r14, %rdi
callq 0x4f8c
movq %rbx, %rdi
callq 0x3230
nop