// File: /workspace/github_cpp_makefile_star2_O2/Gammelkebab[P]GameOfLife/src/world/block.cpp
// Function: Block::Block(World*, int)
Block::Block(World *world, int block_num) : world(world), block_num(block_num)
{
    x = block_num % world->cols;
    y = block_num / world->cols;

    first_row = y == 0;
    first_col = x == 0;
    last_row = y == world->rows - 1;
    last_col = x == world->cols - 1;

    /* Calculate the pixels assigned to this block
     * - Takes care of 8 bit allignment
     * - Takes care of additional pixels from remainder of splitting
     */
    width = world->width / world->cols;
    width -= width % 8;

    /*
     * The remainder after assigning full 8 bit blocks
     * This value is always < world->cols * 8
     * distribute all full 8 bit blocks of the remainder to the first blocks, 
     * then the remaining bits to the last block
     */
    int remainder_x = world->width % (world->cols * 8);
    if (x < remainder_x / 8)
    {
        width += 8;
    }
    if (last_col)
    {
        width += remainder_x % 8;
    }

    // the same for the height
    height = world->height / world->rows;
    height -= height % 8;
    int remainder_y = world->height % (world->rows * 8);
    if (y < remainder_y / 8)
    {
        height += 8;
    }
    if (last_row)
    {
        height += remainder_y % 8;
    }

    // calculate the position of the first (upper left) pixel assigned to this block
    // takes care of additional pixels from remainder of splitting
    starting_x = world->width / world->cols;
    starting_x -= starting_x % 8;
    starting_x *= x;
    starting_x += min(remainder_x / 8, x) * 8; // add all horizontal remainder pixels before this block
    starting_y = world->height / world->rows;
    starting_y -= starting_y % 8;
    starting_y *= y;
    starting_y += min(remainder_y / 8, y) * 8; // add all vertical remainder pixels before this block

    // Create the write buffer grid, containing compressed information about the block
    // 8 Pixels are compressed into one byte
    width_byte = width / 8 + (width % 8 == 0 ? 0 : 1);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl %edx, %eax
movq %rsi, (%rdi)
movl %edx, 0x8(%rdi)
movl 0x10(%rsi), %r11d
cltd
idivl %r11d
movl %eax, %ecx
movl %edx, %r10d
movl %edx, 0xc(%rdi)
movl %eax, 0x10(%rdi)
testl %eax, %eax
sete 0x28(%rdi)
testl %edx, %edx
sete 0x29(%rdi)
movl 0xc(%rsi), %r12d
leal -0x1(%r12), %ebp
cmpl %ebp, %eax
sete 0x2a(%rdi)
leal -0x1(%r11), %r14d
cmpl %r14d, %edx
sete 0x2b(%rdi)
movl (%rsi), %r9d
movl %r9d, %eax
cltd
idivl %r11d
movl %eax, %r8d
movl $0x8, %r15d
cltd
idivl %r15d
movl %edx, %ebx
shll $0x3, %r11d
movl %r9d, %eax
cltd
idivl %r11d
movl %edx, %eax
cltd
idivl %r15d
movl %eax, %r11d
movl %edx, %r9d
subl %ebx, %r8d
leal (%r8,%r15), %eax
cmpl %r11d, %r10d
cmovgel %r8d, %eax
addl %eax, %r9d
cmpl %r14d, %r10d
cmovnel %eax, %r9d
movl %r9d, 0x1c(%rdi)
movl 0x4(%rsi), %ebx
movl %ebx, %eax
cltd
idivl %r12d
movl %eax, %esi
cltd
idivl %r15d
movl %edx, %r14d
shll $0x3, %r12d
movl %ebx, %eax
cltd
idivl %r12d
movl %edx, %eax
cltd
idivl %r15d
movl %esi, %ebx
subl %r14d, %ebx
negl %r14d
cmpl %eax, %ecx
leal 0x8(%rsi,%r14), %esi
cmovgel %ebx, %esi
addl %esi, %edx
cmpl %ebp, %ecx
cmovnel %esi, %edx
movl %edx, 0x20(%rdi)
imull %r10d, %r8d
cmpl %r10d, %r11d
cmovll %r11d, %r10d
leal (%r8,%r10,8), %edx
imull %ecx, %ebx
cmpl %ecx, %eax
cmovll %eax, %ecx
movl %edx, 0x14(%rdi)
leal (%rbx,%rcx,8), %eax
movl %eax, 0x18(%rdi)
movl %r9d, %eax
cltd
idivl %r15d
andl $0x7, %r9d
cmpl $0x1, %r9d
sbbl $-0x1, %eax
movl %eax, 0x24(%rdi)
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
nopl (%rax)