// File: hzeller[P]FlaschenTaschen-PixelPusher-bridge/pixel-pusher-client.cc
// Function: PixelPusherClient::PixelPusherClient(int, int, char const*, char const*, int, int)
PixelPusherClient::PixelPusherClient(int strip_len, int strips,
                                     const char *pp_host,
                                     const char *pp_port,
                                     int max_transmit_bytes, int brightness)
    : width_(strip_len), height_(strips),
      socket_(OpenPPSocket(pp_host, pp_port)),
      // Each row is one byte longer, because we use the first byte to
      // indicate the strip-index which we use in the
      row_size_(1 + sizeof(Color) * width_),
      rows_per_packet_((max_transmit_bytes - 4) / row_size_),
      packets_needed_((height_ + rows_per_packet_ - 1) / rows_per_packet_),
      brightness_percent_(brightness),
      block_dirty_(new bool[packets_needed_]),
      pixel_buffer_(new char[row_size_ * height_]),
      sequence_number_(0) {
    // Prepare the pixel index at the beginning of each row
    memset(pixel_buffer_, 0, row_size_ * height_);
    for (uint8_t i = 0; i < height_; ++i) {
        pixel_buffer_[i * row_size_] = i;
    }
    ResetDirtyFlags();
    if (rows_per_packet_ == 0) {
        fprintf(stderr, "Doh', can't even send a single row per packet ("
                "one row=%d bytes, but max packet-size=%d!)\n",
                (int)row_size_, max_transmit_bytes);
        abort();
    }
    fprintf(stderr, "PP %s: %dx%d; %d UDP packets/frame "
            "(packet contains %d rows @ %d bytes/row)\n",
            pp_host, width_, height_, packets_needed_, rows_per_packet_,
            (int)row_size_);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movl 0x10(%rbp), %eax
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq %rcx, -0x18(%rbp)
movq %r8, -0x20(%rbp)
movl %r9d, -0x24(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x50(%rbp)
callq 0x3930
movq -0x50(%rbp), %rax
leaq 0x6514(%rip), %rcx      # 0xbd10
movq %rcx, (%rax)
movl -0xc(%rbp), %ecx
movl %ecx, 0x8(%rax)
movl -0x10(%rbp), %ecx
movl %ecx, 0xc(%rax)
addq $0x10, %rax
movq %rax, -0x48(%rbp)
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x59d0
movl %eax, -0x3c(%rbp)
jmp 0x5825
movq -0x50(%rbp), %rcx
movq -0x48(%rbp), %rax
movl -0x3c(%rbp), %edx
movl %edx, (%rax)
movslq 0x8(%rcx), %rax
leaq 0x1(%rax,%rax,2), %rax
movq %rax, 0x18(%rcx)
movl -0x24(%rbp), %eax
addl $-0x4, %eax
cltq
movq 0x18(%rcx), %rcx
xorl %edx, %edx
divq %rcx
movq %rax, %rcx
movq -0x50(%rbp), %rax
movl %ecx, 0x20(%rax)
movl 0xc(%rax), %esi
movl 0x20(%rax), %ecx
movl %ecx, %edx
movl %esi, %eax
leal -0x1(%rax,%rdx), %eax
cltd
idivl %ecx
movl %eax, %ecx
movq -0x50(%rbp), %rax
movl %ecx, 0x24(%rax)
movl 0x10(%rbp), %ecx
movl %ecx, 0x28(%rax)
movq %rax, %rcx
addq $0x30, %rcx
movq %rcx, -0x60(%rbp)
movslq 0x24(%rax), %rdi
callq 0x2040
movq %rax, -0x58(%rbp)
jmp 0x5894
movq -0x50(%rbp), %rax
movq -0x60(%rbp), %rcx
movq -0x58(%rbp), %rdx
movq %rdx, (%rcx)
movq %rax, %rcx
addq $0x38, %rcx
movq %rcx, -0x70(%rbp)
movq 0x18(%rax), %rdi
movslq 0xc(%rax), %rax
imulq %rax, %rdi
callq 0x2040
movq %rax, -0x68(%rbp)
jmp 0x58c5
movq -0x50(%rbp), %rax
movq -0x70(%rbp), %rcx
movq -0x68(%rbp), %rdx
movq %rdx, (%rcx)
movl $0x0, 0x40(%rax)
movq 0x38(%rax), %rdi
movq 0x18(%rax), %rdx
movslq 0xc(%rax), %rax
imulq %rax, %rdx
xorl %esi, %esi
callq 0x2110
movb $0x0, -0x35(%rbp)
movq -0x50(%rbp), %rcx
movzbl -0x35(%rbp), %eax
cmpl 0xc(%rcx), %eax
jge 0x593e
movq -0x50(%rbp), %rsi
movb -0x35(%rbp), %dl
movq 0x38(%rsi), %rax
movzbl -0x35(%rbp), %ecx
imulq 0x18(%rsi), %rcx
movb %dl, (%rax,%rcx)
movb -0x35(%rbp), %al
addb $0x1, %al
movb %al, -0x35(%rbp)
jmp 0x58f6
movq -0x50(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
callq 0x3d50
jmp 0x59c1
movq -0x50(%rbp), %rdi
callq 0x5af0
jmp 0x5949
movq -0x50(%rbp), %rax
cmpl $0x0, 0x20(%rax)
jne 0x597d
movq -0x50(%rbp), %rax
movq 0x667a(%rip), %rcx      # 0xbfd8
movq (%rcx), %rdi
movq 0x18(%rax), %rax
movl %eax, %edx
movl -0x24(%rbp), %ecx
leaq 0x2a97(%rip), %rsi      # 0x8408
movb $0x0, %al
callq 0x22a0
callq 0x2120
movq -0x50(%rbp), %rax
movq 0x6650(%rip), %rcx      # 0xbfd8
movq (%rcx), %rdi
movq -0x18(%rbp), %rdx
movl 0x8(%rax), %ecx
movl 0xc(%rax), %r8d
movl 0x24(%rax), %r9d
movl 0x20(%rax), %r10d
movq 0x18(%rax), %rax
leaq 0x2aba(%rip), %rsi      # 0x8463
movl %r10d, (%rsp)
movl %eax, 0x8(%rsp)
movb $0x0, %al
callq 0x22a0
addq $0x80, %rsp
popq %rbp
retq
movq -0x30(%rbp), %rdi
callq 0x2330
nopw (%rax,%rax)