Skip to content

Instantly share code, notes, and snippets.

@taotao54321
Last active August 24, 2021 11:32
Show Gist options
  • Save taotao54321/de7cd10384d970d1ae96e00ee17b53fa to your computer and use it in GitHub Desktop.
Save taotao54321/de7cd10384d970d1ae96e00ee17b53fa to your computer and use it in GitHub Desktop.
Colorize NES ROM using FCEUX CDL
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""FCEUX CDL を利用して ROM を色分け表示
Usage: cdldump foo.bin foo.cdl
requires: colorama
"""
import sys
import argparse
import colorama
from colorama import Fore, Back, Style
# http://www.fceux.com/web/help/fceux.html?CodeDataLogger.html
class FceuxStyler:
def __init__(self): pass
def style(self, cdl_value):
code = cdl_value & (1<<0)
data = cdl_value & (1<<1)
code_ind = cdl_value & (1<<4)
data_ind = cdl_value & (1<<5)
pcm = cdl_value & (1<<6)
if code and data:
return Fore.GREEN
elif pcm:
return Fore.MAGENTA
elif code and code_ind:
return Fore.RED
elif code:
return Fore.YELLOW
elif data and data_ind:
return Fore.CYAN
elif data:
return Fore.BLUE
else:
return Style.RESET_ALL
def chunks(buf, size):
return (buf[i:i+size] for i in range(0, len(buf), size))
def dump(rom, cdl, styler, out):
for off in range(0, len(rom), 16):
rom_chunk = rom[off:off+16]
cdl_chunk = cdl[off:off+16]
out.write("0x{:06X}: ".format(off))
for br, bc in zip(rom_chunk[:8], cdl_chunk[:8]):
dump_byte(br, bc, styler, out)
out.write(" ")
for br, bc in zip(rom_chunk[8:16], cdl_chunk[8:16]):
dump_byte(br, bc, styler, out)
out.write("\n")
def dump_byte(br, bc, styler, out):
out.write(styler.style(bc) + " {:02X}".format(br))
STYLER_MAP = {
"fceux" : FceuxStyler,
}
class ReadAction(argparse.Action):
def __init__(self, option_strings, dest, nargs=None, **kwargs):
if nargs is not None: raise ValueError("nargs not allowed")
super().__init__(option_strings, dest, **kwargs)
def __call__(self, parser, namespace, values, option_string=None):
# argparse.FileType for "-" doesn't work for "rb" mode
# https://bugs.python.org/issue14156
if values is sys.stdin:
values = sys.stdin.buffer
with values as in_:
buf = in_.read()
setattr(namespace, self.dest, buf)
def parse_args():
ap = argparse.ArgumentParser(description="CDL colorizer")
ap.add_argument("rom", type=argparse.FileType("rb"), action=ReadAction)
ap.add_argument("cdl", type=argparse.FileType("rb"), action=ReadAction)
ap.add_argument("--fmt", type=str, choices=sorted(STYLER_MAP), default="fceux")
args = ap.parse_args()
if len(args.rom) != len(args.cdl):
ap.error("size mismatch")
return args
def main():
args = parse_args()
styler = STYLER_MAP[args.fmt]()
colorama.init(autoreset=True, strip=False)
dump(args.rom, args.cdl, styler, sys.stdout)
if __name__ == "__main__": main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment