// File: /workspace/github_c_makefile_star2_O2/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 0x1bf2(%rip), %rsi      # 0x6744
callq 0x22c0
testq %rax, %rax
jne 0x4b7c
movq 0x6495(%rip), %rax      # 0xaff8
movq (%rax), %rdi
leaq 0x2b2e(%rip), %rsi      # 0x769b
movq %rbx, %rdx
xorl %eax, %eax
callq 0x21f0
jmp 0x4c2a
movq %rax, %r12
pushq $0x10
popq %rdi
callq 0x2240
movq %rax, %r15
movq %r12, %rdi
movq %rax, %rsi
callq 0x2607
movq %r15, %rdi
callq 0x2632
testb %al, %al
je 0x4bff
pushq $0x1
popq %rdi
movl $0x2000, %esi           # imm = 0x2000
callq 0x21c0
movq %rax, %r14
movl 0x408(%rbx), %edx
movq %r12, %rdi
movq %r15, %rsi
movq %rax, %rcx
callq 0x2c91
testl %eax, %eax
jne 0x4c3a
movq 0x6428(%rip), %rax      # 0xaff8
movq (%rax), %rdi
movl 0x408(%rbx), %edx
leaq 0x2bdf(%rip), %rsi      # 0x77bf
movq %rbx, %rcx
xorl %eax, %eax
callq 0x21f0
movq %r12, %rdi
callq 0x2100
movq %r15, %rdi
callq 0x2040
movq %r14, %rdi
jmp 0x4c25
movq 0x63f2(%rip), %rax      # 0xaff8
movq (%rax), %rdi
leaq 0x2aa4(%rip), %rsi      # 0x76b4
movq %rbx, %rdx
xorl %eax, %eax
callq 0x21f0
movq %r12, %rdi
callq 0x2100
movq %r15, %rdi
callq 0x2040
movq %rbx, %rdi
callq 0x2040
pushq $0x1
popq %rdi
callq 0x2330
movq %r12, %rdi
callq 0x2100
movq %r15, %rdi
callq 0x2040
leaq 0x80c(%rbx), %rdi
leaq 0x29bc(%rip), %rsi      # 0x7614
callq 0x22c0
testq %rax, %rax
jne 0x4c70
leaq 0x2a91(%rip), %rdi      # 0x76fa
callq 0x22d0
jmp 0x4c32
movq %rax, %r15
movl 0x400(%rbx), %eax
cmpl $0x2, %eax
je 0x4ca8
cmpl $0x1, %eax
jne 0x4ced
pushq $0x1
popq %rdx
movl $0x2000, %esi           # imm = 0x2000
movq %r14, %rdi
movq %r15, %rcx
callq 0x2340
movq %r15, %rdi
callq 0x2100
movq %r14, %rdi
callq 0x2040
jmp 0x4ced
movl $0x8000, %edi           # imm = 0x8000
callq 0x2240
movq %rax, %r12
xorl %r13d, %r13d
cmpq $0x8000, %r13           # imm = 0x8000
je 0x4cd7
leaq (%r12,%r13), %rsi
movq %r14, %rdi
callq 0x26c0
addq $0x40, %r13
addq $0x10, %r14
jmp 0x4cb8
movl 0x404(%rbx), %edx
movq %r12, %rdi
movl $0x200, %esi            # imm = 0x200
movq %r15, %rcx
callq 0x2785
xorl %edi, %edi
callq 0x2330