// File: /workspace/github_cpp_makefile_star2_O1/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 %r14
pushq %rbx
movl %edx, %eax
movq %rsi, (%rdi)
movl %edx, 0x8(%rdi)
movl 0x10(%rsi), %r14d
cltd
idivl %r14d
movl %eax, %ecx
movl %edx, %r8d
movl %edx, 0xc(%rdi)
movl %eax, 0x10(%rdi)
testl %eax, %eax
sete 0x28(%rdi)
testl %edx, %edx
sete 0x29(%rdi)
movl 0xc(%rsi), %ebx
leal -0x1(%rbx), %r11d
cmpl %r11d, %eax
sete 0x2a(%rdi)
leal -0x1(%r14), %ebp
cmpl %ebp, %edx
sete 0x2b(%rdi)
movl (%rsi), %r9d
movl %r9d, %eax
cltd
idivl %r14d
leal 0x7(%rax), %r10d
testl %eax, %eax
cmovnsl %eax, %r10d
andl $-0x8, %r10d
shll $0x3, %r14d
movl %r9d, %eax
cltd
idivl %r14d
leal 0x7(%rdx), %eax
testl %edx, %edx
cmovnsl %edx, %eax
movl %eax, %r9d
sarl $0x3, %r9d
leal 0x8(%r10), %r14d
cmpl %r9d, %r8d
cmovgel %r10d, %r14d
movl %r14d, 0x1c(%rdi)
cmpl %ebp, %r8d
jne 0x39a9
andl $-0x8, %eax
subl %eax, %edx
addl %edx, 0x1c(%rdi)
movl 0x4(%rsi), %esi
movl %esi, %eax
cltd
idivl %ebx
leal 0x7(%rax), %r14d
testl %eax, %eax
cmovnsl %eax, %r14d
andl $-0x8, %r14d
shll $0x3, %ebx
movl %esi, %eax
cltd
idivl %ebx
leal 0x7(%rdx), %esi
testl %edx, %edx
cmovnsl %edx, %esi
movl %esi, %eax
sarl $0x3, %eax
leal 0x8(%r14), %ebx
cmpl %eax, %ecx
cmovgel %r14d, %ebx
movl %ebx, 0x20(%rdi)
cmpl %r11d, %ecx
jne 0x39ee
andl $-0x8, %esi
subl %esi, %edx
addl %edx, 0x20(%rdi)
imull %r8d, %r10d
cmpl %r8d, %r9d
cmovll %r9d, %r8d
leal (%r10,%r8,8), %edx
movl %edx, 0x14(%rdi)
imull %ecx, %r14d
cmpl %ecx, %eax
cmovll %eax, %ecx
leal (%r14,%rcx,8), %eax
movl %eax, 0x18(%rdi)
movl 0x1c(%rdi), %eax
leal 0x7(%rax), %ecx
testl %eax, %eax
cmovnsl %eax, %ecx
sarl $0x3, %ecx
andl $0x7, %eax
cmpl $0x1, %eax
sbbl $-0x1, %ecx
movl %ecx, 0x24(%rdi)
popq %rbx
popq %r14
popq %rbp
retq
nop