// File: /workspace/github_cpp_makefile_star2_O2/miklhh[P]tetris/src/game.cpp
// Function: current_block_rotate(bool)
void current_block_rotate(rotation_t counter_clockwise)
{
    /* Test if the current block can rotate. */
    if (test_rotation(current_block, counter_clockwise) == NO_COLLISION)
    {
        block_rotate(current_block, counter_clockwise);
        return;
    }

    /* Test if a left wall kick can be preformed. */
    block_t temp_block = *current_block;
    block_move(&temp_block, DIRECTION_RIGHT);
    if (test_rotation(&temp_block, counter_clockwise) == NO_COLLISION)
    {
        block_move(current_block, DIRECTION_RIGHT);
        block_rotate(current_block, counter_clockwise);
        return;
    }

    /* Test if a right side wall kick can be preformed. */
    temp_block = *current_block;
    block_move(&temp_block, DIRECTION_LEFT);
    if (test_rotation(&temp_block, counter_clockwise) == NO_COLLISION)
    {
        block_move(current_block, DIRECTION_LEFT);
        block_rotate(current_block, counter_clockwise);
        return;
    }

    //   ------------------------------------------------------------
    //   -------------        SPECTIAL BLOCKS       -----------------
    //   ------------------------------------------------------------

    /* 1x4 block, also known as I-block. */
    if (current_block->block_type == BLOCK_I)
    {
        /* Test a left side double wall kick. */
        temp_block = *current_block;
        for (int i = 0; i < 2; i++)
            block_move(&temp_block, DIRECTION_RIGHT);

        if (test_rotation(&temp_block, counter_clockwise)  == NO_COLLISION)
        {
            for (int i = 0; i < 2; i++)
                block_move(current_block, DIRECTION_RIGHT);

            block_rotate(current_block, counter_clockwise);
            return;
        }



        /* Test a right side double wall kick. */
        temp_block = *current_block;
        for (int i = 0; i < 2; i++)
            block_move(&temp_block, DIRECTION_LEFT);

        if (test_rotation(&temp_block, counter_clockwise) == NO_COLLISION)
        {
            for (int i = 0; i < 2; i++)
                block_move(current_block, DIRECTION_LEFT);

            block_rotate(current_block, counter_clockwise);
            return;
        }
    }
}

// Assembly:
pushq %rbp
pushq %rbx
subq $0x58, %rsp
movl %edi, %ebp
movq 0x3a69(%rip), %rbx      # 0x6ab0
movq %rbx, %rdi
movl %ebp, %esi
callq 0x2a5f
testl %eax, %eax
je 0x30a8
pushq $0x14
popq %rcx
leaq 0x8(%rsp), %rax
movq %rax, %rdi
movq %rbx, %rsi
rep  movsl (%rsi), %es:(%rdi)
incl 0x8(%rax)
movzbl %bpl, %ebp
movq %rax, %rdi
movl %ebp, %esi
callq 0x2a5f
testl %eax, %eax
je 0x30b1
pushq $0x14
popq %rcx
leaq 0x8(%rsp), %rax
movq %rax, %rdi
movq %rbx, %rsi
rep  movsl (%rsi), %es:(%rdi)
decl 0x8(%rax)
movq %rax, %rdi
movl %ebp, %esi
callq 0x2a5f
testl %eax, %eax
je 0x30b5
cmpl $0x0, 0x4(%rbx)
je 0x30cb
addq $0x58, %rsp
popq %rbx
popq %rbp
retq
movzbl %bpl, %esi
movq %rbx, %rdi
jmp 0x30c0
pushq $0x1
jmp 0x30b7
pushq $-0x1
popq %rax
addl %eax, 0x8(%rbx)
movq %rbx, %rdi
movl %ebp, %esi
addq $0x58, %rsp
popq %rbx
popq %rbp
jmp 0x2963
pushq $0x14
popq %rcx
leaq 0x8(%rsp), %rax
movq %rax, %rdi
movq %rbx, %rsi
rep  movsl (%rsi), %es:(%rdi)
addl $0x2, 0x8(%rax)
movq %rax, %rdi
movl %ebp, %esi
callq 0x2a5f
testl %eax, %eax
je 0x3113
pushq $0x14
popq %rcx
leaq 0x8(%rsp), %rax
movq %rax, %rdi
movq %rbx, %rsi
rep  movsl (%rsi), %es:(%rdi)
addl $-0x2, 0x8(%rax)
movq %rax, %rdi
movl %ebp, %esi
callq 0x2a5f
testl %eax, %eax
jne 0x30a1
pushq $-0x2
jmp 0x30b7
pushq $0x2
jmp 0x30b7
nop