// File: 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
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rcx
movq %rcx, (%rax)
movl -0x14(%rbp), %ecx
movl %ecx, 0x8(%rax)
movl -0x14(%rbp), %eax
movq -0x10(%rbp), %rcx
cltd
idivl 0x10(%rcx)
movq -0x28(%rbp), %rax
movl %edx, 0xc(%rax)
movl -0x14(%rbp), %eax
movq -0x10(%rbp), %rcx
cltd
idivl 0x10(%rcx)
movl %eax, %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x10(%rax)
cmpl $0x0, 0x10(%rax)
sete %cl
andb $0x1, %cl
movb %cl, 0x28(%rax)
cmpl $0x0, 0xc(%rax)
sete %cl
andb $0x1, %cl
movb %cl, 0x29(%rax)
movl 0x10(%rax), %ecx
movq -0x10(%rbp), %rdx
movl 0xc(%rdx), %edx
subl $0x1, %edx
cmpl %edx, %ecx
sete %cl
andb $0x1, %cl
movb %cl, 0x2a(%rax)
movl 0xc(%rax), %ecx
movq -0x10(%rbp), %rdx
movl 0x10(%rdx), %edx
subl $0x1, %edx
cmpl %edx, %ecx
sete %cl
andb $0x1, %cl
movb %cl, 0x2b(%rax)
movq -0x10(%rbp), %rax
movl (%rax), %eax
movq -0x10(%rbp), %rcx
cltd
idivl 0x10(%rcx)
movl %eax, %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x1c(%rax)
movl 0x1c(%rax), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movq -0x28(%rbp), %rax
movl 0x1c(%rax), %ecx
subl %edx, %ecx
movl %ecx, 0x1c(%rax)
movq -0x10(%rbp), %rax
movl (%rax), %eax
movq -0x10(%rbp), %rcx
movl 0x10(%rcx), %ecx
shll $0x3, %ecx
cltd
idivl %ecx
movq -0x28(%rbp), %rax
movl %edx, -0x18(%rbp)
movl 0xc(%rax), %eax
movl %eax, -0x20(%rbp)
movl -0x18(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl -0x20(%rbp), %eax
cmpl %ecx, %eax
jge 0xf9e7
movq -0x28(%rbp), %rax
movl 0x1c(%rax), %ecx
addl $0x8, %ecx
movl %ecx, 0x1c(%rax)
movq -0x28(%rbp), %rax
testb $0x1, 0x2b(%rax)
je 0xfa06
movl -0x18(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movq -0x28(%rbp), %rax
addl 0x1c(%rax), %edx
movl %edx, 0x1c(%rax)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x10(%rbp), %rcx
cltd
idivl 0xc(%rcx)
movl %eax, %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x20(%rax)
movl 0x20(%rax), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movq -0x28(%rbp), %rax
movl 0x20(%rax), %ecx
subl %edx, %ecx
movl %ecx, 0x20(%rax)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x10(%rbp), %rcx
movl 0xc(%rcx), %ecx
shll $0x3, %ecx
cltd
idivl %ecx
movq -0x28(%rbp), %rax
movl %edx, -0x1c(%rbp)
movl 0x10(%rax), %eax
movl %eax, -0x2c(%rbp)
movl -0x1c(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl -0x2c(%rbp), %eax
cmpl %ecx, %eax
jge 0xfa77
movq -0x28(%rbp), %rax
movl 0x20(%rax), %ecx
addl $0x8, %ecx
movl %ecx, 0x20(%rax)
movq -0x28(%rbp), %rax
testb $0x1, 0x2a(%rax)
je 0xfa96
movl -0x1c(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movq -0x28(%rbp), %rax
addl 0x20(%rax), %edx
movl %edx, 0x20(%rax)
movq -0x10(%rbp), %rax
movl (%rax), %eax
movq -0x10(%rbp), %rcx
cltd
idivl 0x10(%rcx)
movl %eax, %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x14(%rax)
movl 0x14(%rax), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movq -0x28(%rbp), %rax
movl 0x14(%rax), %ecx
subl %edx, %ecx
movl %ecx, 0x14(%rax)
movl 0xc(%rax), %ecx
imull 0x14(%rax), %ecx
movl %ecx, 0x14(%rax)
movl -0x18(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, %edi
movq -0x28(%rbp), %rax
movl 0xc(%rax), %esi
callq 0xfba0
movl %eax, %ecx
movq -0x28(%rbp), %rax
shll $0x3, %ecx
addl 0x14(%rax), %ecx
movl %ecx, 0x14(%rax)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x10(%rbp), %rcx
cltd
idivl 0xc(%rcx)
movl %eax, %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x18(%rax)
movl 0x18(%rax), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movq -0x28(%rbp), %rax
movl 0x18(%rax), %ecx
subl %edx, %ecx
movl %ecx, 0x18(%rax)
movl 0x10(%rax), %ecx
imull 0x18(%rax), %ecx
movl %ecx, 0x18(%rax)
movl -0x1c(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, %edi
movq -0x28(%rbp), %rax
movl 0x10(%rax), %esi
callq 0xfba0
movl %eax, %ecx
movq -0x28(%rbp), %rax
shll $0x3, %ecx
addl 0x18(%rax), %ecx
movl %ecx, 0x18(%rax)
movl 0x1c(%rax), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq -0x28(%rbp), %rax
movl 0x1c(%rax), %eax
movl $0x8, %esi
cltd
idivl %esi
movq -0x28(%rbp), %rax
movl %edx, %edi
movl $0x1, %edx
xorl %esi, %esi
cmpl $0x0, %edi
cmovel %esi, %edx
addl %edx, %ecx
movl %ecx, 0x24(%rax)
addq $0x30, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)