// File: /workspace/github_c_makefile_star2_O3/sadistech[P]nesromtool2/./src/subcommands/chr.c
// Function: subcommand_chr_extract
void subcommand_chr_extract(chr_opts *opts) {
  // now we're ready to write this stuff out.
  FILE *ifile = fopen(opts->romfile_path, "r");
  if (!ifile) {
    fprintf(stderr, "Failed to open file: %s\n", opts->romfile_path);
    free(opts);
    exit(EXIT_FAILURE);
  }

  // read in the header
  // validate header
  // validate that bank exists
  // extract the bank
  // write the output file

  nrt_header *header = NRT_HEADER_ALLOC;
  nrt_header_extract(ifile, header);

  if (! nrt_validate_header(header)) {
    fprintf(stderr, "Rom file does not look valid: %s\n", opts->romfile_path);
    fclose(ifile);
    free(header);
    free(opts);
    exit(EXIT_FAILURE);
  }

  nrt_chrbank *chr = NRT_CHR_ALLOC;
  if (!nrt_extract_chr(ifile, header, opts->bank_index, chr)) {
    fprintf(stderr, "Failed to read CHR bank %d from %s\n", opts->bank_index, opts->romfile_path);
    fclose(ifile);
    free(header);
    free(chr);
    free(opts);
    exit(EXIT_FAILURE);
  }

  fclose(ifile);
  free(header);

  FILE *ofile = fopen(opts->outfile_path, "w");

  if (!ofile) {
    perror("Failed to open file for writing");
    exit(EXIT_FAILURE);
  }

  if (opts->format == raw_format) {
    // just write out the data to the file.

    fwrite(chr, NRT_CHR_BANK_SIZE, 1, ofile);

    fclose(ofile);
    free(chr);
  } else if (opts->format == png_format) {
    // write out the PNG
    // first, create bitmaps, then write.

    nrt_tile_bitmap *bitmaps = (nrt_tile_bitmap*)malloc(NRT_CHR_TILE_COUNT * sizeof(nrt_tile_bitmap));
    int i;
    for (i = 0; i < NRT_CHR_TILE_COUNT; i++) {
      nrt_tile_to_bitmap(&chr->tile[i], &bitmaps[i]);
    }

    nrt_tiles_to_png(bitmaps, NRT_CHR_TILE_COUNT, opts->width, ofile);
  }

  exit(EXIT_SUCCESS);
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rdi, %rbx
leaq 0x2113(%rip), %rsi      # 0x7744
callq 0x22c0
testq %rax, %rax
jne 0x565b
movq 0x69b6(%rip), %rax      # 0xbff8
movq (%rax), %rdi
leaq 0x304f(%rip), %rsi      # 0x869b
movq %rbx, %rdx
xorl %eax, %eax
callq 0x21f0
jmp 0x570d
movq %rax, %r12
movl $0x10, %edi
callq 0x2240
movq %rax, %r15
movq %r12, %rdi
movq %rax, %rsi
callq 0x2d49
movq %r15, %rdi
callq 0x2d78
testb %al, %al
je 0x56e2
movl $0x1, %edi
movl $0x2000, %esi           # imm = 0x2000
callq 0x21c0
movq %rax, %r14
movl 0x408(%rbx), %edx
movq %r12, %rdi
movq %r15, %rsi
movq %rax, %rcx
callq 0x3411
testl %eax, %eax
jne 0x571f
movq 0x6945(%rip), %rax      # 0xbff8
movq (%rax), %rdi
movl 0x408(%rbx), %edx
leaq 0x30fc(%rip), %rsi      # 0x87bf
movq %rbx, %rcx
xorl %eax, %eax
callq 0x21f0
movq %r12, %rdi
callq 0x2100
movq %r15, %rdi
callq 0x2040
movq %r14, %rdi
jmp 0x5708
movq 0x690f(%rip), %rax      # 0xbff8
movq (%rax), %rdi
leaq 0x2fc1(%rip), %rsi      # 0x86b4
movq %rbx, %rdx
xorl %eax, %eax
callq 0x21f0
movq %r12, %rdi
callq 0x2100
movq %r15, %rdi
callq 0x2040
movq %rbx, %rdi
callq 0x2040
movl $0x1, %edi
callq 0x2330
movq %r12, %rdi
callq 0x2100
movq %r15, %rdi
callq 0x2040
leaq 0x80c(%rbx), %rdi
leaq 0x2ed7(%rip), %rsi      # 0x8614
callq 0x22c0
testq %rax, %rax
jne 0x5755
leaq 0x2fac(%rip), %rdi      # 0x86fa
callq 0x22d0
jmp 0x5715
movq %rax, %r15
movl 0x400(%rbx), %eax
cmpl $0x2, %eax
je 0x578f
cmpl $0x1, %eax
jne 0x57d2
movl $0x2000, %esi           # imm = 0x2000
movl $0x1, %edx
movq %r14, %rdi
movq %r15, %rcx
callq 0x2340
movq %r15, %rdi
callq 0x2100
movq %r14, %rdi
callq 0x2040
jmp 0x57d2
movl $0x8000, %edi           # imm = 0x8000
callq 0x2240
movq %rax, %r12
xorl %r13d, %r13d
leaq (%r12,%r13), %rsi
movq %r14, %rdi
callq 0x2e18
addq $0x40, %r13
addq $0x10, %r14
cmpq $0x8000, %r13           # imm = 0x8000
jne 0x579f
movl 0x404(%rbx), %edx
movq %r12, %rdi
movl $0x200, %esi            # imm = 0x200
movq %r15, %rcx
callq 0x2ed8
xorl %edi, %edi
callq 0x2330